Home > database >  Firebase Function that looks into child collection documents for update and returns sum of values in
Firebase Function that looks into child collection documents for update and returns sum of values in

Time:11-12

My Firestore database is setup as follow:

/users/{userId}/tenants/{tenantId}/invoices/{invoiceId}

In each invoice document (InvoiceId), there are [“status”] and [“amount”] fields. ["status"] can be either “Pending” or “Paid”.

Every time there is an update to “status” inside of an invoiceId document, I would like to get the sum of all “amounts” where "status" == “Pending” from the respective invoice collection that was just updated. Then I want to set this new balance data to the respective tenantId document.

The following script calculates the sum for all documents where "status" == "Pending" whenever an invoiceId document is updated. However, I would like to calculate the sum of "amounts" only for the invoice collection that was updated (not all).

For example: suppose there's tenants A and B, each with many invoices. An invoice under tenant A is updated. I would like to calculate the new sum of "amounts" for tenant A (and not B).

Let me know if this is even possible.

exports.invoiceUpdated = functions.firestore
    .document('/users/{userId}/tenants/{tenantId}/invoices/{invoiceId}')
    .onUpdate(async (snap, context) => {

        const task = await (db.collectionGroup('invoices').where('status', '==', "Pending").get());

        if (task.empty) {
            console.log('No pending invoices...')
            return;
        }
        var total= 0;
        task.forEach(element => {
            console.log(element.data().amount)
            total  = element.data().amount

        })

    });```

CodePudding user response:

When you are using the following document reference:

/users/{userId}/tenants/{tenantId}/invoices/{invoiceId}

It means that you are trying to get updates of a single invoice that corresponds to a single user.

On the other hand, in the following query:

db.collectionGroup('invoices').where('status', '==', "Pending")

Since you are using a collectionGroup, it means that you are trying to filter documents from all "invoices" sub-collections, where the "status" field holds the value of "Pending". This means that you'll get all documents from your entire database, no matter what the user is.

The following script calculates the sum for all documents where "status" == "Pending" whenever an invoiceId document is updated. However, I would like to calculate the sum of "amounts" only for the invoice collection that was updated (not all).

If you want to check if the "status" of an invoice that corresponds to a single user has changed, then you should use the following reference:

/users/{userId}/tenants/{tenantId}/invoices/

And to calculate the new sum, the same reference should be added, as it points only to the invoices that correspond to a single user.

However, calculating the sum of all invoices, every time the status of a single invoice has changed, might not be the best option. You should consider adding a count that should be updated every time the status of an invoice is changed. This means that when you want to inform the user about the new sum, a single read operation will be involved. Otherwise, you'll have to pay a number of reads that is equal to the number of documents that your query returns.

CodePudding user response:

This is a similar question to this: Firestore - get the parent document of a subcollection

In general, what you need to do is to get the parent document from the child document, which can be done with:

snapshot.getRef().getParent()

  • Related