We used to have to do a lot of weird things to be able to count documents on Firestore, like keeping track of the aggregation on separate documents.

Starting October 2022 Firebase 9.12.1 now offers a native way to solve this.

Let’s say you have a collection of users on your database, and you want to know how many users you have.

In the past, you would have created a cloud function that would add 1 to the user’s stats document every time the user was created.

Now, you don’t have to keep track of that, you can simply use the getCountFromServer() method, for example:

import { getCountFromServer, getFirestore, collection } from 'firebase/firestore';

getTotalUsers(): void {
  const firestore = getFirestore();
  const userCollectionReference = collection(firestore, "users");
  const userCollectionSnapshot = await getCountFromServer(userCollectionReference);
  return userCollectionSnapshot.data().count;
}

Or let’s say you want to know how many paid users you have, you can create a query and get the count from there:

import { getCountFromServer, getFirestore, collection, query } from 'firebase/firestore';

getTotalUsers(): void {
  const firestore = getFirestore();
  const userCollectionReference = collection(firestore, "users");
  const userCollectionSnapshot = await getCountFromServer(userCollectionReference);
  return userCollectionSnapshot.data().count;
}

getPaidUsers(): void {
  const firestore = getFirestore();
  const userCollectionReference = collection(firestore, "users");
  // The query is going to depend on how you define paid users
  const paidUserQuery = query(userCollectionReference, where("status", "==", "paid"));
  const userCollectionSnapshot = await getCountFromServer(paidUserQuery);
  return userCollectionSnapshot.data().count;
}

Limitations

It is a good idea to keep track of the Firebase docs for the limitations on this.

But the short version is:

  • Results come from the Firestore server, they skip the cached/local data.
  • If it is a complex aggregation that takes more than 60 seconds it’ll error out.