Home
>
Firestore Server Count and Snapshot Size

Firestore Server Count and Snapshot Size

9 min read
Jonathan Gamble

jdgamble555 on Tuesday, January 30, 2024 (last modified on Wednesday, February 21, 2024)

Counting the number of documents in a collection or in a query can be quite a task. However, in most cases there is no reason to overthink it. You probably don’t need to worry about data modeling correctly to count your data, as Firestore can probably handle your use case out of the box. This is especially true for starter apps, prototyping, or proof of concept apps.

TL;DR

Method ✅ Best For ⚠️ Avoid When
Snapshot Size
Counting documents you have already queried. Counting documents you have not already read.
Server Count Counting less than 1000 documents quickly. Counting large collections occasionally. Counting medium to large collections frequently.
You need to sort by a counter.
You need a realtime counter.

Using the Snapshot Size

If you have already read all your documents, there is no reason to recount them. Simply use JavaScript to get the number of documents you have read. This is basically getting the length of the array, and displaying that number. However, Firebase has a specific method size for that.

⚠️ Do not use for counting the number documents you have not already read.

JavaScript SDK

	const querySnapshot = await getDocs(
    collection(db, 'posts')
);

const count = querySnapshot.size;

You could equally get the count for any query.

	const querySnapshot = await getDocs(
    query(
        collection(db, 'posts'),
        where('uid', '==', uid)
    )
);

const count = querySnapshot.size;

Keep in mind this only works for counting documents you have already queried. You don’t want to use this to count documents you don’t need to display on your page. Normally you would limit the number of documents you query at one time. This will not display a total if you have limit in your query, it will only display the number of documents you have in your current query snapshot, or in your results. Here the count could at most be 5, even if you have more than 5 documents in your collection.

	const querySnapshot = await getDocs(
    query(
        collection(db, 'posts'),
        limit(5)
    )
);

const count = querySnapshot.size;

Node.js SDK

You may also need to do this in on the server. This is also what you may would use on the Edge, Firebase Cloud Functions, or even Bun or Deno depending on compatibility.

	const querySnapshot = await db.collection('posts').get();

const count = querySnapshot.size;

Or with a limit, with a maximum of 5.

	
const querySnapshot = await db.collection('posts').limit(5).get();

const count = querySnapshot.size;

Alternative to size

In all these cases, you could just manually count the length of the array. You get the same number.

	const count = querySnapshot.docs.length;

Using the Server Count

getCountFromServer is probably the easiest option. It allows you to count your documents on Google's server, and return the actual count without returning each document’s data. This is probably the method most people are going to use to count documents. It is best for queries or collections with less than 1000 documents. You could use an alternative method, for example, to count all posts, but use this method to count all posts by a certain user. An individual user has probably not written 1000 documents, while you could have 100,000 posts.

📌 This method does not work with Realtime Updates.

JavaScript SDK

	const countQuerySnapshot = await getCountFromServer(
    collection(db, 'posts')
);

const postCount = countQuerySnapshot.data().count;

You can input a collection, or a query.

	const countQuerySnapshot = await getCountFromServer(
    query(
        collection(db, 'posts'),
        where('uid', '==', uid)
    )
);

const postCount = countQuerySnapshot.data().count;

Keep in mind you do NOT want to use a limit inside your server count, as this will be part of the query you are counting, and will still return a maximum value of that limit, not the full query size.

Node.js SDK

Node has the count method that will return the full count.

	const countQuerySnapshot = await db
    .collection('posts')
    .where('uid', '==', uid)
    .count()
    .get();

const postCount = countQuerySnapshot.data().count;

Pricing

One of the biggest problems with getCountFromServer or using the count() method in Node.js is the cost. For a small database, it is only 1 document read. However, if you have more than 1000 documents, you are charged 1 document read for each 1-1000 documents you read. That means a query or collection with results of 1600 documents get charged 2 document reads, 3400 gets charged 4 document reads etc. Of course, if you’re using caching mechanisms, this may not be a problem.

When to Use Alternative Methods

Do not use size to count any number of documents you have not read. You probably do not want to use getCountFromServer for counting queries with more than 1000 documents, especially if you need to display it on pages that are not cached and get lots of page views. You also cannot sort by a count that is calculated, nor can you display a realtime count update using these techniques. Generally speaking, you want to use a combination of counting techniques in your app as your app complexity grows, and it will depend on your use case.


Related Posts

© 2024 Code.Build