Unexpected Behavior When Query by .whereArrayContains()





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I have a RecyclerView that utilizes the FireaseUI and orders all objects from the "Polls" node by the "timestamp" field (sequentially).



New Fragment - .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);

}
});
}


I have another layout in my app that subscribes to this same node, but instead queries by "followers" and then by "timestamp.:



Following Fragment - .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);

}
});
}


In the first scenario, UI items populate, in real-time, into my RecyclerView as they are added to Firebase. However, when I query by ".whereArrayContains," I do not get this same behavior, and I was curious as to why. The items only reappear when I restart the application:



enter image description here



Edit:



I commented out the below line:



// .whereArrayContains("followers", mUserId)



and the behavior performed as expected, therefore I can isolate the issue to the .whereArrayContains() query. It is the only difference between each Fragment.










share|improve this question































    1















    I have a RecyclerView that utilizes the FireaseUI and orders all objects from the "Polls" node by the "timestamp" field (sequentially).



    New Fragment - .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);

    }
    });
    }


    I have another layout in my app that subscribes to this same node, but instead queries by "followers" and then by "timestamp.:



    Following Fragment - .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);

    }
    });
    }


    In the first scenario, UI items populate, in real-time, into my RecyclerView as they are added to Firebase. However, when I query by ".whereArrayContains," I do not get this same behavior, and I was curious as to why. The items only reappear when I restart the application:



    enter image description here



    Edit:



    I commented out the below line:



    // .whereArrayContains("followers", mUserId)



    and the behavior performed as expected, therefore I can isolate the issue to the .whereArrayContains() query. It is the only difference between each Fragment.










    share|improve this question



























      1












      1








      1








      I have a RecyclerView that utilizes the FireaseUI and orders all objects from the "Polls" node by the "timestamp" field (sequentially).



      New Fragment - .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);

      }
      });
      }


      I have another layout in my app that subscribes to this same node, but instead queries by "followers" and then by "timestamp.:



      Following Fragment - .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);

      }
      });
      }


      In the first scenario, UI items populate, in real-time, into my RecyclerView as they are added to Firebase. However, when I query by ".whereArrayContains," I do not get this same behavior, and I was curious as to why. The items only reappear when I restart the application:



      enter image description here



      Edit:



      I commented out the below line:



      // .whereArrayContains("followers", mUserId)



      and the behavior performed as expected, therefore I can isolate the issue to the .whereArrayContains() query. It is the only difference between each Fragment.










      share|improve this question
















      I have a RecyclerView that utilizes the FireaseUI and orders all objects from the "Polls" node by the "timestamp" field (sequentially).



      New Fragment - .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);

      }
      });
      }


      I have another layout in my app that subscribes to this same node, but instead queries by "followers" and then by "timestamp.:



      Following Fragment - .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);

      }
      });
      }


      In the first scenario, UI items populate, in real-time, into my RecyclerView as they are added to Firebase. However, when I query by ".whereArrayContains," I do not get this same behavior, and I was curious as to why. The items only reappear when I restart the application:



      enter image description here



      Edit:



      I commented out the below line:



      // .whereArrayContains("followers", mUserId)



      and the behavior performed as expected, therefore I can isolate the issue to the .whereArrayContains() query. It is the only difference between each Fragment.







      java android firebase google-cloud-firestore firebaseui






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 24 '18 at 4:50









      Frank van Puffelen

      247k31392420




      247k31392420










      asked Nov 24 '18 at 2:48









      tccpg288tccpg288

      1,19711536




      1,19711536
























          1 Answer
          1






          active

          oldest

          votes


















          1














          This is happening because when you are using whereArrayContains() and orderBy() methods in the same query, an index is required. To use one, go to your Firebase Console and create it manually or if you are using Android Studio, you'll find in your logcat a message that sounds like this:




          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: ...




          You can simply click on that link or copy and paste the url into a web broswer and you index will be created automatically.




          Why is this index needed?




          As you probably noticed, queries in Cloud Firestore are very fast and this is because Firestore automatically creates an indexes for any fields you have in your document. When you need to order your items, a particular index is required that should be created as explained above. However, if you intend to create the index manually, please also select from the dropdown the corresponding Array contains option, as in the below image:



          enter image description here






          share|improve this answer


























          • Worked! Thanks for the help.

            – tccpg288
            Nov 24 '18 at 13:00












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53454763%2funexpected-behavior-when-query-by-wherearraycontains%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          This is happening because when you are using whereArrayContains() and orderBy() methods in the same query, an index is required. To use one, go to your Firebase Console and create it manually or if you are using Android Studio, you'll find in your logcat a message that sounds like this:




          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: ...




          You can simply click on that link or copy and paste the url into a web broswer and you index will be created automatically.




          Why is this index needed?




          As you probably noticed, queries in Cloud Firestore are very fast and this is because Firestore automatically creates an indexes for any fields you have in your document. When you need to order your items, a particular index is required that should be created as explained above. However, if you intend to create the index manually, please also select from the dropdown the corresponding Array contains option, as in the below image:



          enter image description here






          share|improve this answer


























          • Worked! Thanks for the help.

            – tccpg288
            Nov 24 '18 at 13:00
















          1














          This is happening because when you are using whereArrayContains() and orderBy() methods in the same query, an index is required. To use one, go to your Firebase Console and create it manually or if you are using Android Studio, you'll find in your logcat a message that sounds like this:




          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: ...




          You can simply click on that link or copy and paste the url into a web broswer and you index will be created automatically.




          Why is this index needed?




          As you probably noticed, queries in Cloud Firestore are very fast and this is because Firestore automatically creates an indexes for any fields you have in your document. When you need to order your items, a particular index is required that should be created as explained above. However, if you intend to create the index manually, please also select from the dropdown the corresponding Array contains option, as in the below image:



          enter image description here






          share|improve this answer


























          • Worked! Thanks for the help.

            – tccpg288
            Nov 24 '18 at 13:00














          1












          1








          1







          This is happening because when you are using whereArrayContains() and orderBy() methods in the same query, an index is required. To use one, go to your Firebase Console and create it manually or if you are using Android Studio, you'll find in your logcat a message that sounds like this:




          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: ...




          You can simply click on that link or copy and paste the url into a web broswer and you index will be created automatically.




          Why is this index needed?




          As you probably noticed, queries in Cloud Firestore are very fast and this is because Firestore automatically creates an indexes for any fields you have in your document. When you need to order your items, a particular index is required that should be created as explained above. However, if you intend to create the index manually, please also select from the dropdown the corresponding Array contains option, as in the below image:



          enter image description here






          share|improve this answer















          This is happening because when you are using whereArrayContains() and orderBy() methods in the same query, an index is required. To use one, go to your Firebase Console and create it manually or if you are using Android Studio, you'll find in your logcat a message that sounds like this:




          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: ...




          You can simply click on that link or copy and paste the url into a web broswer and you index will be created automatically.




          Why is this index needed?




          As you probably noticed, queries in Cloud Firestore are very fast and this is because Firestore automatically creates an indexes for any fields you have in your document. When you need to order your items, a particular index is required that should be created as explained above. However, if you intend to create the index manually, please also select from the dropdown the corresponding Array contains option, as in the below image:



          enter image description here







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 24 '18 at 10:41

























          answered Nov 24 '18 at 10:33









          Alex MamoAlex Mamo

          47.5k82965




          47.5k82965













          • Worked! Thanks for the help.

            – tccpg288
            Nov 24 '18 at 13:00



















          • Worked! Thanks for the help.

            – tccpg288
            Nov 24 '18 at 13:00

















          Worked! Thanks for the help.

          – tccpg288
          Nov 24 '18 at 13:00





          Worked! Thanks for the help.

          – tccpg288
          Nov 24 '18 at 13:00




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53454763%2funexpected-behavior-when-query-by-wherearraycontains%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Academy of Television Arts & Sciences

          L'Équipe

          1995 France bombings