簡體   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