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

时间:2018-01-31 04:48:25

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

我正在尝试获取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的方法吗?

3 个答案:

答案 0 :(得分:8)

我们在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());
        }
    }
});

上述示例适用于小型数据集,但如果数据集较大,则无法正常工作。但是,还有两种方法可以实现同样的目的。

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

如果您需要超出此限制,则需要按照official documentation of distributed counters中的说明实施distributed counters

  

作为个人提示,请勿在Cloud Firestore中存储此类计数器,因为每次增加或减少计数器都会花费readwrite次操作。在Firebase Realtime数据库中免费托管此计数器

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

作为结论,使用第一个代码用于小型数据集,第二个使用云函数,因为写入时间尽力而为,第三个使用我在上面解释过的最后一个选项。

答案 1 :(得分:1)

在onCompelete()里面检查 使用日志之前if (task.isSuccessful())。并且您可以像for (DocumentSnapshot document : task.getResult()){ yourCounter++;}一样遍历documentSnapShot并在每次迭代时递增counter以了解集合"Posts"下有多少文档可用

答案 2 :(得分:1)

我确实通过这段代码解决了我的问题:

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;
        }
     }
});