2

I would like to chain query in firestore. I need some informations about one collections before get other information in an other collection.

I have already try to use Tasks.whenall()... but doesn't efficient. I try to use callBack too.

Here my first function :

public static void getAllFavoris(){
    String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
    FirebaseFirestore.getInstance().collection("product").document("favoris").collection(uid).get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {//task is succesful
                        Log.e("TAG","task succes for fav ");
                        for (QueryDocumentSnapshot document : task.getResult()){//never enter in this loop
                            Log.e("TAG","Doc "+document);
                            Log.e("TAG", "Succes for get all favoris");
                            Log.e("TAG","data for favoris ::: "+document.getId());
                            MainActivity.favorisList.add(document.getId());
                        }
                    }
                    else {
                        Log.d("TAG", "Error getting documents: ", task.getException());
                    }
//call without data retrieve
                    Log.e("TAG","favoris ::: "+showListContentS(MainActivity.favorisList));
                    getProductByTagFound();
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Log.e("TAG","error get All favoris"+e);
                }
            });
}

And here the second query i need :

public static void getProductByTagFound(){
for(int i=0;i<MainActivity.allTags.size();i++){ //allTags is not empty and i need to finish this loop
    String tagId = MainActivity.allTags.get(i).toString();
    FirebaseFirestore.getInstance().collection("product").document("allProduct").collection("productByTag").document(tagId).get()
            .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                @Override
                public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                    if (task.isSuccessful()){
                            Log.e("TAG", "Succes for get productByTag");
                            Product pdt = task.getResult().toObject(Product.class);
                            MainActivity.productByTag.add(pdt);

                    }
                }
            });
}
//this must be call after the loop is finish but call in the same time.
Log.e("TAG","Get product BY Tag"+showListContentP(MainActivity.productByTag));
createFinalList();

}

I need that to call createFinalList() after the loop finish and also to enter in the loop for favoris get data and call getProductByTag() after.

Thelouras
  • 852
  • 1
  • 10
  • 30
Arno
  • 91
  • 2
  • 11

1 Answers1

1

If you want to perform a new query right after the first one is finished, you need to wait untill the first query completes. To sovle this, you need to use nested queries. With other words, you need to move the second query right inside the first callback, inside onComplete() method. In this way, the second query will be performed only when the first one completes.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • I know that but in my method `getProductByTagFound()` the `onComplete()` is in a `for()` loop and i need to finish the loop and after call the other method. – Arno Jul 10 '19 at 09:42
  • So you basically want to perform another query right after the first iteration ends, right? And in the same way, the second query and so on. Is this waht you want? – Alex Mamo Jul 10 '19 at 09:51
  • In the `getProductByTagFound()` i want to perform `createFinalList()` when the last ietration is finish. For the moment `createFinalList()` is perform before i finish the iteration. And for the `getAllFavoris` I never enter in the `or (QueryDocumentSnapshot document : task.getResult())` so I never get the data i need. – Arno Jul 10 '19 at 09:55
  • 1
    In this case, you should create a Task object for every iteration in your loop and add to a `List>` and then call `whenAllSuccess()` method as explained in my answer from this **[post](https://stackoverflow.com/questions/51892766/android-firestore-convert-array-of-document-references-to-listpojo/51897261)**. Does it work this way? – Alex Mamo Jul 10 '19 at 10:16
  • I try it but it didn't work. In your post you have `for()` in a `OnComplete()` or in my case I try to get data in a `for()`. – Arno Jul 10 '19 at 11:42
  • 1
    It's the **exact** same use-case, everytime you call `get()` a Task object is returned so at every iteration, add that Task object to a list. Them simply call `whenAllSuccess()` and that's it. – Alex Mamo Jul 10 '19 at 11:48
  • ok that work for this thanks, but did you know why in `getAllFavoris()` i can't enter in `for (QueryDocumentSnapshot document : task.getResult())`? – Arno Jul 10 '19 at 12:00
  • 1
    You should debug that code (for loop) using breakpoints to see where the code fails. – Alex Mamo Jul 10 '19 at 12:03