0

In my application I have a function where I display some data in RecyclerView and for that I need a list of data.

I have a collection (ActiveJobs) and its documents have a field of string array called jobApplicantsId, and have another collection called Repairmen. My task is to list all of the documents from Repairmen collection where the document id is the same as in the specific ActiveJobs document array field.

Actually I did the first half of the task, I can get the corresponding documents, but as you can see the code from below, I'm using a query inside a for loop, which is inside another query! My problem is that I can't get matchingDocs outside the for loop because of async communication.

    public void getApplicants(String docID, final GetListCallback callback) {
    final List<DocumentSnapshot> matchingDocs = new ArrayList<>();
    fStore.collection("ActiveJobs").document(docID).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if (task.isSuccessful()) {
                DocumentSnapshot doc = task.getResult();
                ArrayList<String> list = (ArrayList<String>) doc.get("jobApplicantsId");
                for (int i = 0; i < list.size(); i++) {
                    fStore.collection("Repairmen").whereEqualTo("repID", list.get(i)).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                        @Override
                        public void onComplete(@NonNull Task<QuerySnapshot> task) {
                            if (task.isSuccessful()) {
                                for (DocumentSnapshot doc : task.getResult()) {
                                    matchingDocs.add(doc);
                                    Log.d("list", matchingDocs.toString());   //getting the right results
                                }
                            }
                        }
                    });
                }
            }
            Log.d("list", matchingDocs.toString());   //matchingDocs is empty here
        }
    });
}

I think I have to use Tasks.whenall()... but I can't actually know how can I make this work. Thanks for your time and help!

d_vain
  • 15
  • 4
  • You're almost there. To solve this, please move the line `Log.d("list", matchingDocs.toString());` right after where the second for loop ends. Remember, any code that needs data from the Cloud Firestore needs to be inside the onComplete method, or be called from there. Please check the duplicate to see how can you solve this using a custom callback or Kotlin Coroutines. – Alex Mamo Feb 02 '21 at 12:38
  • Hey, Alex! I was able to make it work thanks to your help on [this](https://stackoverflow.com/questions/55865448/run-multiple-firestore-queries-and-wait-for-all-of-them-to-be-completed) question. I had to make the query inside the for loop as Task, and then call whenAllSuccess on this query outside the for loop. Then I was able to pass the matchingDocs with a callback. Thank you!:) – d_vain Feb 02 '21 at 13:17
  • Good to hear that ;) You're very welcome, d_vain! – Alex Mamo Feb 02 '21 at 13:43

0 Answers0