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!