如何计算 Firestore 中集合下的文档数?
Posted
技术标签:
【中文标题】如何计算 Firestore 中集合下的文档数?【英文标题】:How to count the number of documents under a collection in Firestore? 【发布时间】:2018-07-10 02:54:15 【问题描述】:我正在尝试获取 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
的另一种方法?
【问题讨论】:
在使用日志之前在 onCompelete() 中检查if (task.isSuccessful())
。您还可以像for (DocumentSnapshot document : task.getResult()) yourCounter++;
一样遍历documentSnapShot
,并在每次迭代时递增计数器,以了解“帖子”集合下有多少文档可用。
谢谢,我已经尝试过 'if (task.isSuccessful())' 以确保它不起作用,问题出在 Integer fromWhereToStart 的行中,我也没有使用 count++因为我只是添加数据不需要获取整个文档,但是如果我找不到解决方案,我可能会使用这个想法,再次感谢您
所以您要计算Posts
集合中的所有文档?这是你想要的吗?
@AlexMamo 是的,有没有办法在不获取整个数据的情况下获取计数
@MohammedFarhan 你也可以添加你的评论作为答案
【参考方案1】:
编辑: 2021 年 7 月 10 日
最近,Firebase 添加了一个名为Distributed Counter 的新扩展:
使用此扩展程序为您的应用添加高度可扩展的计数器服务。这对于计算病毒式操作或任何非常高速的操作(例如查看、喜欢或分享)的应用程序来说是理想的。
使用此扩展,您还可以超过每秒一次写入操作的最大限制。
这里还有一篇您可能感兴趣的文章:
How to count the number of documents in a Firestore collection?因为我们在 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 Quotas and Limits 中所述。这是一个要阅读的文档,但它几乎可以立即向您显示当前计数。
如果您需要超出此限制,您需要按照official documentation of distributed counters 中的说明实施distributed counters
。
作为个人提示,不要将这种计数器存储在 Cloud Firestore 中,因为每次增加或减少计数器都会花费您一次
read
或write
操作。在Firebase Realtime
数据库中托管此计数器几乎免费。
第二种方法是,而不是使用 Cloud Functions,而是在客户端使用事务,在添加或删除文档的同时更新计数器。这样,您的计数器也会准确,因为它是同时更新的。但在这种情况下,最重要的是,您需要确保在添加或删除文档的任何地方都包含此逻辑。在这种情况下,您也可以免费使用 Firebase 实时数据库。
总之,将第一个代码用于小型数据集,第二个代码使用 Cloud Functions,因为它是写入时的尽力而为,第三个代码使用我在上面向您解释过的最后一个选项。
【讨论】:
谢谢,这行得通,但是没有获取全部数据就没有办法获取它们吗? 不幸的是,我们在 Firebase 实时数据库 getChildrenCout() 中没有 getDocumentCount() 方法。 非常感谢您的帮助,我认为他们必须为我创建一个方法然后 xD 请看我更新的答案。希望您对 Cloud Firestore 中的文档计数有更好的了解。 这与谁先回答无关,而是您需要检查是否已接受您认为对您更有用的答案。这也将有助于将来阅读问题/答案的访问者。【参考方案2】:在 onCompelete() 内部检查
if (task.isSuccessful())
使用日志之前。您还可以像for (DocumentSnapshot document : task.getResult()) yourCounter++;
一样遍历documentSnapShot,并在每次迭代时递增counter
,以了解集合"Posts"
下有多少文档可用
【讨论】:
【参考方案3】:我确实通过这段代码解决了我的问题:
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;
);
【讨论】:
纯代码答案并不是特别有用。请添加一些关于此代码如何解决问题的说明。以上是关于如何计算 Firestore 中集合下的文档数?的主要内容,如果未能解决你的问题,请参考以下文章
在 React 本机移动应用程序中集成 firestore 时获得“firestore/permission-denied”
Firebase Firestore 中一个集合下的文档数量限制
如何使用 Flutter 在 Firestore 中删除具有特定值的多个文档