通过 .whereArrayContains() 查询时的意外行为
Unexpected Behavior When Query by .whereArrayContains()
我有一个 RecyclerView,它利用 FireaseUI 并通过 "timestamp" 字段(顺序)对 "Polls" 节点中的所有对象进行排序。
新片段 - .onViewCreated()
Query queryStore = FirebaseFirestore.getInstance()
.collection(POLLS_LABEL)
.orderBy("timestamp", Query.Direction.ASCENDING);
//Cloud Firestore does not have any ordering; must implement a timestampe to order sequentially
FirestoreRecyclerOptions<Poll> storeOptions = new FirestoreRecyclerOptions.Builder<Poll>()
.setQuery(queryStore, Poll.class)
.build();
mFirestoreAdaper = new FirestoreRecyclerAdapter<Poll, PollHolder>(storeOptions) {
@Override
protected void onBindViewHolder(@NonNull final PollHolder holder, final int position, @NonNull Poll model) {
holder.mPollQuestion.setText(model.getQuestion());
String voteCount = String.valueOf(model.getVote_count());
//TODO: Investigate formatting of vote count for thousands
holder.mVoteCount.setText(voteCount);
Picasso.get()
.load(model.getImage_URL())
.fit()
.into(holder.mPollImage);
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent toClickedPoll = new Intent(getActivity(), PollHostActivity.class);
String recyclerPosition = getSnapshots().getSnapshot(position).getId();
Log.v("Firestore ID", recyclerPosition);
toClickedPoll.putExtra("POLL_ID", recyclerPosition);
startActivity(toClickedPoll);
}
});
}
我的应用程序中有另一个布局订阅了同一个节点,而是通过 "followers" 查询,然后通过“timestamp.:
以下片段 - .onViewCreated()
Query queryStore = FirebaseFirestore.getInstance()
.collection(POLLS_LABEL)
.whereArrayContains("followers", mUserId)
.orderBy("timestamp", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<Poll> storeOptions = new FirestoreRecyclerOptions.Builder<Poll>()
.setQuery(queryStore, Poll.class)
.build();
mFirestoreAdaper = new FirestoreRecyclerAdapter<Poll, PollHolder>(storeOptions) {
@Override
protected void onBindViewHolder(@NonNull final PollHolder holder, final int position, @NonNull Poll model) {
holder.mPollQuestion.setText(model.getQuestion());
String voteCount = String.valueOf(model.getVote_count());
//TODO: Investigate formatting of vote count for thousands
holder.mVoteCount.setText(voteCount);
Picasso.get()
.load(model.getImage_URL())
.fit()
.into(holder.mPollImage);
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent toClickedPoll = new Intent(getActivity(), PollHostActivity.class);
String recyclerPosition = getSnapshots().getSnapshot(position).getId();
Log.v("Firestore ID", recyclerPosition);
toClickedPoll.putExtra("POLL_ID", recyclerPosition);
startActivity(toClickedPoll);
}
});
}
在第一个场景中,UI 个项目在 real-time 中填充到我的 RecyclerView 中,因为它们被添加到 Firebase。然而,当我通过“.whereArrayContains”查询时,我没有得到同样的行为,我很好奇为什么。这些项目仅在我重新启动应用程序时重新出现:
编辑:
我注释掉了下面一行:
// .whereArrayContains("followers", mUserId)
并且行为按预期执行,因此我可以将问题隔离到 .whereArrayContains() 查询。这是每个片段之间的唯一区别。
发生这种情况是因为当您在同一个查询中使用 whereArrayContains()
和 orderBy()
方法时,index is required. To use one, go to your Firebase Console 并手动创建它,或者如果您使用 Android Studio,您会在 logcat 中找到一条听起来像这样的消息:
W/Firestore: (0.6.6-dev) [Firestore]: Listen for Query(products where array array_contains YourItem order by timestamp) failed: Status{code=FAILED_PRECONDITION, description=The query requires an index. You can create it here: ...
您只需单击 link 或将 url 复制并粘贴到网络浏览器中,您的索引就会自动创建。
Why is this index needed?
您可能已经注意到,Cloud Firestore 中的查询非常快,这是因为 Firestore 会自动为文档中的任何字段创建索引。当您需要订购商品时,需要一个特定的索引,该索引应按上述说明创建。但是,如果您打算手动创建索引,请也从下拉列表中 select 相应的 Array contains
选项,如下图所示:
我有一个 RecyclerView,它利用 FireaseUI 并通过 "timestamp" 字段(顺序)对 "Polls" 节点中的所有对象进行排序。
新片段 - .onViewCreated()
Query queryStore = FirebaseFirestore.getInstance()
.collection(POLLS_LABEL)
.orderBy("timestamp", Query.Direction.ASCENDING);
//Cloud Firestore does not have any ordering; must implement a timestampe to order sequentially
FirestoreRecyclerOptions<Poll> storeOptions = new FirestoreRecyclerOptions.Builder<Poll>()
.setQuery(queryStore, Poll.class)
.build();
mFirestoreAdaper = new FirestoreRecyclerAdapter<Poll, PollHolder>(storeOptions) {
@Override
protected void onBindViewHolder(@NonNull final PollHolder holder, final int position, @NonNull Poll model) {
holder.mPollQuestion.setText(model.getQuestion());
String voteCount = String.valueOf(model.getVote_count());
//TODO: Investigate formatting of vote count for thousands
holder.mVoteCount.setText(voteCount);
Picasso.get()
.load(model.getImage_URL())
.fit()
.into(holder.mPollImage);
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent toClickedPoll = new Intent(getActivity(), PollHostActivity.class);
String recyclerPosition = getSnapshots().getSnapshot(position).getId();
Log.v("Firestore ID", recyclerPosition);
toClickedPoll.putExtra("POLL_ID", recyclerPosition);
startActivity(toClickedPoll);
}
});
}
我的应用程序中有另一个布局订阅了同一个节点,而是通过 "followers" 查询,然后通过“timestamp.:
以下片段 - .onViewCreated()
Query queryStore = FirebaseFirestore.getInstance()
.collection(POLLS_LABEL)
.whereArrayContains("followers", mUserId)
.orderBy("timestamp", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<Poll> storeOptions = new FirestoreRecyclerOptions.Builder<Poll>()
.setQuery(queryStore, Poll.class)
.build();
mFirestoreAdaper = new FirestoreRecyclerAdapter<Poll, PollHolder>(storeOptions) {
@Override
protected void onBindViewHolder(@NonNull final PollHolder holder, final int position, @NonNull Poll model) {
holder.mPollQuestion.setText(model.getQuestion());
String voteCount = String.valueOf(model.getVote_count());
//TODO: Investigate formatting of vote count for thousands
holder.mVoteCount.setText(voteCount);
Picasso.get()
.load(model.getImage_URL())
.fit()
.into(holder.mPollImage);
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent toClickedPoll = new Intent(getActivity(), PollHostActivity.class);
String recyclerPosition = getSnapshots().getSnapshot(position).getId();
Log.v("Firestore ID", recyclerPosition);
toClickedPoll.putExtra("POLL_ID", recyclerPosition);
startActivity(toClickedPoll);
}
});
}
在第一个场景中,UI 个项目在 real-time 中填充到我的 RecyclerView 中,因为它们被添加到 Firebase。然而,当我通过“.whereArrayContains”查询时,我没有得到同样的行为,我很好奇为什么。这些项目仅在我重新启动应用程序时重新出现:
编辑:
我注释掉了下面一行:
// .whereArrayContains("followers", mUserId)
并且行为按预期执行,因此我可以将问题隔离到 .whereArrayContains() 查询。这是每个片段之间的唯一区别。
发生这种情况是因为当您在同一个查询中使用 whereArrayContains()
和 orderBy()
方法时,index is required. To use one, go to your Firebase Console 并手动创建它,或者如果您使用 Android Studio,您会在 logcat 中找到一条听起来像这样的消息:
W/Firestore: (0.6.6-dev) [Firestore]: Listen for Query(products where array array_contains YourItem order by timestamp) failed: Status{code=FAILED_PRECONDITION, description=The query requires an index. You can create it here: ...
您只需单击 link 或将 url 复制并粘贴到网络浏览器中,您的索引就会自动创建。
Why is this index needed?
您可能已经注意到,Cloud Firestore 中的查询非常快,这是因为 Firestore 会自动为文档中的任何字段创建索引。当您需要订购商品时,需要一个特定的索引,该索引应按上述说明创建。但是,如果您打算手动创建索引,请也从下拉列表中 select 相应的 Array contains
选项,如下图所示: