0

Actually I want to create a Admin Panel for my website and I need to show the total number of users that signed up today(or in the last week). I want to fetch the number of user documents that were created in the users collection today. I have a createdOn field in every user document.

Can I do something like this:

admin.firestore()
  .collection('user')
  .where('createdOn', '>', <today's midnight timestamp here>)
  .count()

Like is there any hack/solution for fetching count of documents without actually fetching them.

Anirudh
  • 3
  • 3
  • 1
    Does this answer your question? [Cloud Firestore collection count](https://stackoverflow.com/questions/46554091/cloud-firestore-collection-count) – Sergio Jul 15 '20 at 09:07
  • Or in https://stackoverflow.com/questions/53532615 – Sergio Jul 15 '20 at 09:09

1 Answers1

1

Since there is no COUNT()in Firestore (as yet) you are forced to query your documents to calculate or maintain the total number of records globally or based on arguments.

There is an extension to do just that but I had trouble configuring it.

I personaly use a simple Cloud functions that I know is not completely bulletproof but good enough to provide me with a dbutils collection where I store the latest count of any collection. I also maintain count subcollections to store the number of records for the same collection but with query parameters. Quite necessary to propose a REST API...

import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'

export const dbutils = functions
   .firestore.document('/{collection}/{id}')
   .onWrite((change, context) => {
      const db = admin.firestore()
      const docRef = `dbutils/${context.params.collection}`
      let value = 0

      if (!change.before.exists) {
         value += 1 // new record
      } else if (!change.after.exists) {
         value -= 1 // deleted record
      }
      // ignore last case which is update

      if (value !== 0) {
         db.doc(docRef)
            .set(
               {
                  count: admin.firestore.FieldValue.increment(value),
                  updatedAt: Date.now(),
               },
               { merge: true },
            )
            .then(res => deleteCollection(db, `${docRef}/counts`, 500))
            .catch(err => console.log(err))
      }

      return null
   })

const deleteCollection = (
   db: admin.firestore.Firestore,
   collectionPath: string,
   batchSize: number,
) => {
   const collectionRef = db.collection(collectionPath)
   const query = collectionRef.orderBy('__name__').limit(batchSize)

   return new Promise((resolve, reject) => {
      deleteQueryBatch(db, query, batchSize, resolve, reject)
   })
}

I'm confident we'll get a COUNT() sooner or later!

Olivier Lépine
  • 618
  • 5
  • 14