【问题标题】:How to know that Snapshot Listener is finished | firestore?如何知道 Snapshot Listener 已经完成 |火库?
【发布时间】:2025-09-24 19:30:03
【问题描述】:

我有这段代码可以从特定的子集合中获取数据:

 db.collection("groups").document(id.get(i)).collection("members")
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()) {
                            for (QueryDocumentSnapshot document : task.getResult()) {
                                id.add(document.getId());
                                Log.e(Tag, document.getId() + " => " + document.getData());

                                if (task.getResult().isEmpty()) {
                                    Log.d(Tag, "onSuccess: LIST EMPTY");
                                    return;
                                } else {
                                    // Convert the whole Query Snapshot to a list
                                    // of objects directly! No need to fetch each
                                    // document.
                                    Log.e(Tag, task.getResult() + "");
                                    typeAll = task.getResult().toObjects(GroupMembers.class);
                                }
                            }
                        } else {
                            Log.e(Tag, "Error getting documents: ", task.getException());
                        }

但是我需要在通过快照获取所有数据后调用一个方法。如何做到这一点?我应该测试什么?

【问题讨论】:

    标签: java android firebase google-cloud-firestore


    【解决方案1】:

    如何知道 Snapshot Listener 结束了?

    快照侦听器始终在侦听更改,除非您是 removing it

    如果您想知道何时完成从数据库加载数据,请注意,您无法知道所有 members 何时完成下载,因为 Cloud Fireatore 是一个实时数据库并且正在获取数据可能永远不会完成。这就是为什么将其命名为实时数据库,因为在任何时候members 集合下的数据都可以更改,可以添加或删除属性。

    您只能在写入更新数据时使用CompletionListener,当Firebase服务器确认操作但您无法使用时,您会收到通知读取数据时这个界面。

    【讨论】:

    • 非常感谢,很好的解释。我需要的是在获取新数据后调用我的适配器,我使用处理程序等待 5 秒,但这不是正确的方法
    • 这似乎是另一个问题,但我认为您应该调用notifyDataSetChanged() 方法以刷新适配器或在需要时创建新实例。
    • 您认为我的回答对您有帮助吗?
    • 好的,试试看,让我知道。
    【解决方案2】:

    在检索对象列表后调用您的方法来处理它:

                               if (task.isSuccessful()) {
                                    for (QueryDocumentSnapshot document : task.getResult()) {
                                        id.add(document.getId());
                                        Log.e(Tag, document.getId() + " => " + document.getData());
    
                                        if (task.getResult().isEmpty()) {
                                            Log.d(Tag, "onSuccess: LIST EMPTY");
                                            return;
                                        } else {
                                            // Convert the whole Query Snapshot to a list
                                            // of objects directly! No need to fetch each
                                            // document.
                                            Log.e(Tag, task.getResult() + "");
                                            typeAll = task.getResult().toObjects(GroupMembers.class);
    
                                            // do something with typeall here
    
                                        }
                                    }
                                } else {
                                    Log.e(Tag, "Error getting documents: ", task.getException());
                                }
    

    【讨论】: