【问题标题】:Run multiple Firestore queries and wait for all of them to be completed运行多个 Firestore 查询并等待所有查询完成
【发布时间】:2019-04-26 10:16:07
【问题描述】:

在我的应用程序中,我想在开始片段之前对我的数据库执行 4 次查询。

不知何故,我试图实现的是:

Task t1 = Query1.get().onSuccesListener.... ; 
Task t2 = Query2.get().onSuccesListener.... ; 
Task t3 = Query3.get().onSuccesListener.... ; 
Task t4 = Query4.get().onSuccesListener.... ; 

我无论如何都找不到在 Android 中使用 Task 来执行它们,所以我尝试在 AsynTask 内运行查询,然后使用 Latch onPostExecuted 等待所有 AsyncTask 完成。

这里是我的 AsyncTask 之一的示例。

private class GetLandlordsRoomQuery extends AsyncTask<Void, Void, Void> {
        ArrayList<RoomPosted> landlordsRooms = new ArrayList<>();
        @Override
        protected Void doInBackground(Void... voids) {
            Query removeNonTenant = FirebaseFirestore.getInstance()
                    .collection(DataBasePath.ROOMS.getValue())
                    .whereEqualTo("landlordID", FirebaseAuth.getInstance().getUid());

            removeNonTenant.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                    for (DocumentSnapshot d : queryDocumentSnapshots) {
                        landlordsRooms.add(d.toObject(RoomPosted.class));
                    }
                }
            });
            return null;
        }
        @Override
        public void onPostExecute(Void result) {
            mLandlordsRooms = landlordsRooms;
            if (--asyncTaskLatch == 0){
                startFragmentFromLandlord();
            }
        }
    }

我在这里运行的问题是 onPostExecuted 在查询完成之前运行。

我可能使用 AsyncTask 解决此问题的方法有误,但找不到使用 Task 等待所有 4 项任务完成而不使用它们嵌套 onCompleteListener 的方法。

有什么想法可以并行运行所有 4 个线程并等待它们完成,然后再加载我的框架?

【问题讨论】:

  • 如果您希望在文档或查询发生更改时收到通知,则只能使用侦听器。如果您只想一次获取文档或查询结果,请使用 get()。 Firestore 查询都是异步的,因此您无需使用 AsyncTask 添加任何线程。

标签: java android firebase android-asynctask google-cloud-firestore


【解决方案1】:

您可以使用 Tasks 的 whenAllSuccess() 方法简单地在本地合并所有 4 个单独的查询。您可以使用以下代码行来实现这一点:

Task t1 = Query1.get();
Task t2 = Query2.get();
Task t3 = Query3.get();
Task t4 = Query4.get();

Task combinedTask = Tasks.whenAllSuccess(t1, t2, t3, t4).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
    @Override
    public void onSuccess(List<Object> list) {
         //Do what you need to do with your list
    }
});

如您所见,当覆盖 onSuccess() 方法时,结果是您从这些查询中获得的对象的 list

Cloud Firestore 客户端已在后台线程中运行所有网络操作。这意味着所有操作都不会阻塞您的主线程。将其放入AsyncTask 不会带来任何额外的好处。

【讨论】:

  • 谢谢,我现在就试试。我想我只是因为使用 AsyncTask 过于复杂了。
  • 一如既往,感谢@AlexMamo 的回答。他们工作完美。
  • 让我再问一个问题@AlexMamo。如果查询之一(出于任何原因)失败。都失败了?我看到了一个类似的调用“whenAllComplete”。我想当您可以控制某些任务的“失败”时使用这种方法,对吗?或者只是失败了?谢谢!
  • @Shudy 要跟踪故障,除了onSuccess() 之外,您还应该实现onFailure()。这样,您就可以知道您的读取操作会发生什么。
猜你喜欢
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-23
  • 2020-03-22
  • 1970-01-01
相关资源
最近更新 更多