Herbie Vine
Herbie Vine

Reputation: 2025

Way to query and update data in Firestore

I run a payment system with Stripe and am trying to decrement a quantity field in Firestore after every successful purchase. I can get the document but I'm struggling figuring out how to update it.

db.collection('products').where('id', '==', dbRef).get()
    .then(querySnapshot => {
        return querySnapshot.forEach(doc => {
            return res.json({
                data: doc.data(),
                err: err
            })
        })
    })
{
  "data": {
    "stripe": {
      "sku": "sku_xxx",
      "product": "prod_xxx"
    },
    "name": "VERSA HOODIE",
    "id": "pmz0pvfa",
    "createdBy": "Q3Vn0LLRnSWzxaeOK7V0UYbuiKF2",
    "price": "25.00",
    "quantity": 10,
    "inStock": true,
    "description": "TEST PRODUCT",
    "imageURL": "https://xxx"
  },
  "err": null
}

I tried stuff like doc.update({}), but it doens't work... Thanks in advance

Upvotes: 1

Views: 254

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83191

(If your query always returns one and only one document, see below)


To update all the documents returned by a query, you need to call the update() method of the DocumentReferences, as follows:

db.collection('products').where('id', '==', dbRef).get()
    .then(querySnapshot => {
        querySnapshot.forEach(doc => {
            const docRef = doc.ref;
            docRef.update({...});
        })
    })

If you want to know when all the updates are done, and possibly add to the promise chain another call to an asynchronous method, you should use Promise.all() as follows:

db.collection('products').where('id', '==', dbRef).get()
    .then(querySnapshot => {
        const promises = [];
        querySnapshot.forEach(doc => {
            const docRef = doc.ref;
            promises.push(docRef.update({...}));
        })
        return Promise.all(promises);
    })
    .then(...)

Note that if you are sure you have less than 500 updates to be done, you could use a set of batched writes.


If you know that there is only ONE document corresponding to the query, just do as follows:

db.collection('products').where('id', '==', dbRef).get()
    .then(querySnapshot => {
        const docRef = querySnapshot.docs[0].ref;
        return docRef.update({...});
    })

Finally, note that if you want to increment or decrement a field in Firestore, you should use FieldValue.increment()

Upvotes: 2

Related Questions