0

In our app we are trying to fetch all the products and by iterating each product trying to get specificationId which is equal to another documentId in seperate collection Specifications.

Basically the structure is like below:

ProductDetail

  • productId
  • productTitle
  • productDescription
  • specificationId

Specification

  • documentId — this is autogenerated id for collection which is being used as specificationId in ProductDetail collection.

MainActivity.java

Query productResponseQuery = FirebaseFirestore.getInstance()
            .collection("productdetails")
            .limit(50);

    productResponseQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void onEvent(@Nullable QuerySnapshot querySnapshot, @Nullable FirebaseFirestoreException error) {

            if (error != null) {
                Log.d(TAG, "Error getting documents: " + error.getMessage());
                return;
            }

            querySnapshot.forEach(doc -> {
                ProductDetailResponse productDetailResponse = new ProductDetailResponse();
                productDetailResponse.setProductImage(doc.getData().get("productImageUrl").toString());
                productDetailResponse.setProductTitle(doc.getData().get("productTitle").toString());
                productDetailResponse.setProductShortDesc(doc.getData().get("productShortDesc").toString());
                productDetailResponse.setProductDesc(doc.getData().get("productDescription").toString());

               populateSpecification(doc.getData().get("specId").toString());

            });
        }
    });

 private void populateSpecification(String specId){
    DocumentReference specDocumentRef = FirebaseFirestore.getInstance()
            .collection("specifications")
            .document(specId);

    specDocumentRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if(task.getResult().exists()){
                task.getResult();
            }else{
                task.getException();
            }
        }
    });
}

I understand that the Firestore database calls are asynchronous in nature. Hence if I call the specificationQuery inside the for loop, without waiting for the result it is jumping to the next iteration.

Is there any way without changing the structure I can achieve the result, which will basically show all the product details along with their respective specification collection?

Laurel
  • 5,965
  • 14
  • 31
  • 57
anand
  • 1,711
  • 2
  • 24
  • 59
  • 1
    It sounds like you want to wait for all those tasks to complete. I recommend checking out the [Become a Firebase Taskmaster](https://firebase.blog/posts/2016/09/become-a-firebase-taskmaster-part-1) blog series, specifically [part 4](https://firebase.blog/posts/2016/10/become-a-firebase-taskmaster-part-4) which covers `Tasks.whenAll`. – Frank van Puffelen Jun 13 '22 at 18:09
  • 3
    Does this answer your question? [Firebase Firestore: How to acess a collection from another collection](https://stackoverflow.com/questions/60145265/firebase-firestore-how-to-acess-a-collection-from-another-collection) – Rogelio Monter Jun 13 '22 at 23:14
  • 1
    I think this [answer](https://stackoverflow.com/questions/63698816/java-firestore-get-multiple-documents-from-firestore-using-an-arraylist-of-do/) will also help. – Alex Mamo Jun 14 '22 at 08:35

0 Answers0