How to get the number of documents under a firestore collection?
With the size
property of the QuerySnapshot
, you can get the number of documents of a collection, as follows:
db.collection("comments").get().then(function(querySnapshot) {
console.log(querySnapshot.size);
});
HOWEVER, you should note that this implies that you read all the documents of the collection each time you want to get the number of documents and, therefore, it has a cost.
So, if your collection has a lot of documents, a more affordable approach would be to maintain a set of distributed counters that hold the number of documents. Each time you add/remove a document, you increase/decrease the counters.
Based on the documentation, here is how to do for a write:
First, initialize the counters:
const db = firebase.firestore();
function createCounter(ref, num_shards) {
let batch = db.batch();
// Initialize the counter document
batch.set(ref, { num_shards: num_shards });
// Initialize each shard with count=0
for (let i = 0; i < num_shards; i++) {
let shardRef = ref.collection('shards').doc(i.toString());
batch.set(shardRef, { count: 0 });
}
// Commit the write batch
return batch.commit();
}
const num_shards = 3; //For example, we take 3
const ref = db.collection('commentCounters').doc('c'); //For example
createCounter(ref, num_shards);
Then, when you write a comment, use a batched write as follows:
const num_shards = 3;
const ref = db.collection('commentCounters').doc('c');
let batch = db.batch();
const shard_id = Math.floor(Math.random() * num_shards).toString();
const shard_ref = ref.collection('shards').doc(shard_id);
const commentRef = db.collection('comments').doc('comment');
batch.set(commentRef, { title: 'Comment title' });
batch.update(shard_ref, {
count: firebase.firestore.FieldValue.increment(1),
});
batch.commit();
For a document deletion you would decrement the counters, by using: firebase.firestore.FieldValue.increment(-1)
Finally, see in the doc how to query the counter value!
How to Count the number of document in a particular collection in firestore flutter and display at Scaffold Text widget
Since this is an async operation, you can use a FutureBuilder
to wrap the Text
widget and use it in the Scaffold
.
FutureBuilder(
future: collectionReference.get(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List myDocCount = snapshot.data.docs;
var totalStudent = myDocCount.length.toString();
return Text(totalStudent.toString());
} else {
return Center(child: CircularProgressIndicator());
}
},
);
Get number of documents in collection firestore
Firestore (like many NoSQL databases) has no built in aggregation queries. If you want to determine the number of documents, you have two main options:
- Read all documents, and then count them in the client.
- Keep the document count in the database itself, and then update it with every add/delete operation.
While the firsts option is simpler, it is less scalable as you'll end up with clients reading all documents just to determine the count. That's why you'll find most questions/articles about counting documents focusing on the second approach.
For more on this, see:
- The Firestore documentation on aggregation queries.
- The Firestore documentation on distributed counters, which you'll need to consider if your count changes more frequently than about once per second.
How to count the number of documents under a collection in Firestore?
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:
- How to count the number of documents in a Firestore collection?
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 awrite
operation. Host this counter in theFirebase 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.
How to get a count of number of documents in a collection with Cloud Firestore
You currently have 3 options:
Option 1: Client side
This is basically the approach you mentioned. Select all from collection and count on the client side. This works well enough for small datasets but obviously doesn't work if the dataset is larger.
Option 2: Write-time best-effort
With this approach, you can use Cloud Functions to update a counter for each addition and deletion from the collection.
This works well for any dataset size, as long as additions/deletions only occur at the rate less than or equal to 1 per second. This gives you a single document to read to give you the almost current count immediately.
If need need to exceed 1 per second, you need to implement distributed counters per our documentation.
Option 3: Write-time exact
Rather than using Cloud Functions, in your client you can update the counter at the same time as you add or delete a document. This means the counter will also be current, but you'll need to make sure to include this logic anywhere you add or delete documents.
Like option 2, you'll need to implement distributed counters if you want to exceed per second
Related Topics
Firestore Whereequalto, Orderby and Limit(1) Not Working
One Time Login in App - Firebaseauth
How to Implement Custom Action Bar With Custom Buttons in Android
How to Execute Python Script from Java (Via Command Line)
How to Create a Generic Array in Java
How to Create a Java String from the Contents of a File
How to Remove Repeated Elements from Arraylist
Streamcorruptedexception: Invalid Type Code: Ac
How to Read the Value of a Private Field from a Different Class in Java
Firebase Ui Authentication With Google Fails With Message (Code:10 Message:10)
Showing Firebase Data in Listview
Difference Between Jsonobject and Jsonarray
Rjava Load Error in Rstudio/R After "Upgrading" to Osx Yosemite
Int Division: Why Is the Result of 1/3 == 0
What Is a Serialversionuid and Why Should I Use It