Firestore collectionReference returns all documents

Viewed 3491

I am using Firebase Firestore to query some documents with a certain id. This is my structure:

EDIT: SCREENSHOT AND DESCRIPTION ADDED JUST AFTER THIS LINE:

generatedId and id have the same value. I have a list of these "id" and I want to search the public_messages collection to return a list of items which my provided list of "id".

firestore structure

root
----- public_messages
---------- generatedId
-------------------- name
-------------------- id  
---------- generatedId
-------------------- name
-------------------- id  
----- other data

I am using the following code to query the messages with a certain id:

 ArrayList<String> keys ... (this has some keys)

    CollectionReference collectionReference = firebaseFirestore.collection("public_messages");

    for (String id : keys) {
        collectionReference.whereEqualTo("id", id);
    }

    collectionReference.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {
                int count = 0;
                for (QueryDocumentSnapshot document : task.getResult()) {
                    count++;
                }
                loog("total messages = " + count);
            } else {
                Log.d("TAG", "Error getting documents: ", task.getException());
            }
        }
    });

In onComplete, the variable task.getResult() returns all the documents in the said collection. Consequently, the variable count represents the total number of documents in the said collection.

I want to only query the results with the specified ids. The number of ids can exceed 10 (which is apparently the limit set by Google, and which limit I was trying to evade by using a for-loop). What should I do?

3 Answers

The key to solving this problem is to use Tasks's whenAllSuccess(Collection> tasks):

Returns a Task with a list of Task results that completes successfully when all of the specified Tasks complete successfully.

Like in the following lines of code:

CollectionReference collectionReference = FirebaseFirestore.getInstance().collection("public_messages");
ArrayList<String> ids = new ArrayList<>(); //Contains your keys
ArrayList<Task<QuerySnapshot>> tasks = new ArrayList<>();
for (String id : ids) {
    Task<QuerySnapshot> task = collectionReference.whereEqualTo("id", id).get();
    tasks.add(task);
}

Tasks.whenAllSuccess(tasks).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
    @Override
    public void onSuccess(List<Object> list) {
        //Do what you need to do with your list
        for (Object object : list) {
            PublicMessage publicMessage = ((DocumentSnapshot) object).toObject(PublicMessage.class);
        }
        Log.d("TAG", "Finished getting all " + list.size() + " documents");
    }
});

When the onSuccess() fires, you'll be sure that you've got absolutely all documents.

Try the following

CollectionReference collectionReference =

firebaseFirestore.collection("public_messages").whereIn("id", keys);

collectionReference.get().addOnCompleteListener(..);

Try this:

// getting a reference to the collection
const collectionRef = collection(getFirestore(), 'COLLECTION-NAME');

//get the documents from the collection by its ref.
const querySnapshot = await getDocs(collectionRef);

// now you can run for each document with simple loop 
querySnapshot.forEach((document) => {
  console.log(document.id, ' => ', document.data());
});
Related