【问题标题】:How chain queries in firestore and wait retrieve data如何在 Firestore 中进行链式查询并等待检索数据
【发布时间】:2019-07-10 08:27:09
【问题描述】:

我想在firestore 中链接查询。在获取另一个集合中的其他信息之前,我需要一些关于一个集合的信息。

我已经尝试过使用Tasks.whenall()... 但没有效率。 我也尝试使用callBack

这是我的第一个功能:

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);
                }
            });
}

这是我需要的第二个查询:

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();

}

我需要在循环完成后调用createFinalList(),并进入循环以获取收藏数据并在之后调用getProductByTag()

【问题讨论】:

    标签: java android firebase google-cloud-firestore


    【解决方案1】:

    如果您想在第一个查询完成后立即执行新查询,则需要等到第一个查询完成。为了解决这个问题,您需要使用嵌套查询。换句话说,您需要将第二个查询移到第一个回调中,在 onComplete() 方法中。这样,只有在第一个查询完成后,才会执行第二个查询。

    【讨论】:

    • 我知道,但在我的方法getProductByTagFound() 中,onComplete() 处于for() 循环中,我需要在调用其他方法后完成循环。
    • 所以你基本上想在第一次迭代结束后立即执行另一个查询,对吧?以同样的方式,第二个查询等等。这是你想要的吗?
    • 在这种情况下,您应该为循环中的每个迭代创建一个 Task 对象并添加到 List&lt;Task&lt;DocumentSnapshot&gt;&gt;,然后调用 whenAllSuccess() 方法,正如我在此 @987654321 的回答中所解释的那样@。是这样的吗?
    • 这是 exact 相同的用例,每次调用 get() 时都会返回一个 Task 对象,因此在每次迭代时,将该 Task 对象添加到列表中。他们只需调用whenAllSuccess() 即可。
    • 您应该使用断点调试该代码(for 循环)以查看代码失败的位置。
    猜你喜欢
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    • 2021-01-09
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    相关资源
    最近更新 更多