Edit: October 20th, 2022
Starting from now, counting the documents in a collection or the documents that are returned by a query is actually possible without the need for keeping a counter. So you can count the documents using the new count() method which:
Returns a query that counts the documents in the result set of this query.
This new feature was announced at this year's Firebase summit. Keep in mind that this feature doesn't read the actual documents. So according to the official documentation:
For aggregation queries such as count(), you are charged one document read for each batch of up to 1000 index entries matched by the query. For aggregation queries that match 0 index entries, there is a minimum charge of one document read.
For example, count() operations that match between 0 and 1000 index entries are billed for one document read. For A count() operation that matches 1500 index entries, you are billed 2 document reads.
Edit: July 10th, 2021
Recently, Firebase added a new Extension called Distributed Counter:
Use this extension to add a highly scalable counter service to your app. This is ideal for applications that count viral actions or any very high-velocity action such as views, likes, or shares.
Using this Extension, you can also get over the max limit of one write operation/second.
Here is also an article that you might be interested in:
Becasue there is no getDocumentCount()
method as we have in Firebase Realtime database, a getChildrenCount()
method, to actually count the number of all documents beneath your Posts
collection from your Cloud Firestore, please use the following code:
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());
}
}
});
or
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());
}
}
});
The above examples work well enough for small datasets but it doesn't work if the dataset is larger. But, there are also two more ways in which you can achieve the same thing.
One way would be to use Cloud Functions to update a counter
every time you add or delete a document from your Posts
collection. This technique works well also for big datasets. But note, in this case, the additions and deletions of documents can only occur at the rate less than or equal to 1 per second, as described in Cloud Firestore Quotas and Limits. That is a single document to read but it shows you the current count almost instantly.
If there is a need for you to exceed this limitation, you need to implement distributed counters
as explained in the official documentation of distributed counters.
As a personal hint, don't store this kind of counter in Cloud Firestore, because every time you increase or decrease the counter will cost you a read
or a write
operation. Host this counter in the Firebase Realtime
database almost at no cost.
The second way would be, rather than using Cloud Functions, to use transactions at your client-side, to update the counter at the same time as you add or delete a document. In this way, your counter will also be accurate, because it is updated at the same time. But the most important thing, in this case, is that you'll need to make sure to include this logic anywhere you add or delete a document. You can use in this case Firebase Realtime database as well, at no cost.
In conclusion, use the first code for small datasets, the second use Cloud Functions because is write-time best-effort, and the third use the last option I have explained to you above.
if (task.isSuccessful())
before using logs. and also you can iterate over thedocumentSnapShot
likefor (DocumentSnapshot document : task.getResult()){ yourCounter++;}
and increment counter on each iteration to know how many documents under collection "Posts" are available. – ImpolitePosts
collection? Is this what you want? – Fetid