繁体   English   中英

如何计算 Firestore 集合下的文档数量?

[英]How to count the number of documents under a collection in Firestore?

我正在尝试获取 Cloud Firestore 上存在的CollectionReference计数,我尝试使用以下方法获取它:

FirebaseFirestore db = FirebaseFirestore.getInstance();
    final CollectionReference postsCollection = db.collection("Posts");

    final TaskCompletionSource<Integer> source = new TaskCompletionSource<>();
    new Thread(new Runnable() {
        @Override
        public void run() {
            int fromWhereToStart = postsCollection.get().getResult().size();
            source.setResult(fromWhereToStart);
        }
    }).start();

    Task<Integer> task = source.getTask();
    task.addOnCompleteListener(new OnCompleteListener<Integer>() {
        @Override
        public void onComplete(@NonNull Task<Integer> task) {
            Log.e("Z_fromWhereToStart", "= " + task.getResult());
        }
    });

但不幸的是,我得到:

java.lang.IllegalStateException: Task is not yet complete

有没有另一种方法来获得另一种修复IllegalStateException方法的计数?

编辑: 2021 年 7 月 10 日

最近,Firebase 添加了一个名为Distributed Counter的新扩展:

使用此扩展程序向您的应用程序添加高度可扩展的计数器服务。 这对于计算病毒式操作或任何非常高速的操作(例如查看、喜欢或分享)的应用程序来说是理想的。

使用此扩展,您还可以克服每秒一次写入操作的最大限制。

这里还有一篇你可能感兴趣的文章:


因为我们在 Firebase 实时数据库中没有getDocumentCount()方法,一个getChildrenCount()方法来实际计算来自 Cloud Firestore 的Posts集合下的所有文档的数量,请使用以下代码:

db.collection("Posts").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            int count = 0;
            for (DocumentSnapshot document : task.getResult()) {
                count++;
            }
            Log.d("TAG", count + "");
        } else {
            Log.d(TAG, "Error getting documents: ", task.getException());
        }
    }
});

或者

db.collection("Posts").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            Log.d("TAG", task.getResult().size() + "");
        } else {
            Log.d(TAG, "Error getting documents: ", task.getException());
        }
    }
});

上面的例子对于小数据集足够好,但如果数据集更大,它就不起作用。 但是,还有另外两种方法可以实现相同的目标。

一种方法是在每次从Posts集合中添加或删除文档时使用Cloud Functions更新counter 这种技术也适用于大数据集。 但请注意,在这种情况下,文档的添加和删除只能以小于或等于每秒 1 次的速度发生,如Cloud Firestore 配额和限制中所述 这是一个要阅读的单个文档,但它几乎立即显示了当前计数。

如果您需要超出此限制,则需要按照distributed counters官方文档中的 说明实现分布式计数器

作为个人提示,不要在 Cloud Firestore 中存储这种计数器,因为每次增加或减少计数器都会花费您一次readwrite操作。 Firebase Realtime数据库中几乎免费托管此计数器。

第二种方法是,而不是使用 Cloud Functions,在客户端使用事务,在添加或删除文档的同时更新计数器。 这样,您的计数器也将是准确的,因为它是同时更新的。 但最重要的是,在这种情况下,您需要确保在添加或删除文档的任何位置都包含此逻辑。 在这种情况下,您也可以免费使用 Firebase 实时数据库。

总之,对于小数据集使用第一个代码,第二个使用 Cloud Functions 因为是写入时尽力而为,第三个使用我在上面向您解释的最后一个选项。

在使用日志之前,在 onCompelete() 中检查if (task.isSuccessful()) 并且您还可以像for (DocumentSnapshot document : task.getResult()){ yourCounter++;}迭代 documentSnapShot 并在每次迭代时增加counter以了解集合"Posts"有多少文档可用

我确实通过以下代码解决了我的问题:

db.collection("Posts").get().addOnCompleteListener(new 
 OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
               count = task.getResult().size();              
        } else {
               Toast.makeTesxt(getContext(),"Error : " + 
                                         e.toString(),Toast.LENGHT_LONG).show;
        }
     }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM