[英]How to count the number of documents filtered by a query in Cloud 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 中存储这种计数器,因为每次增加或减少计数器都会花费您一次
read
或write
操作。 在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.