7

I have a Firebase Firestore database, in which I have a collection users. There is an array in the collection and in the array there is a map. In the map, there is a field qty. I want to increment that qty field value.

Using increment doesnt help as the qty is inside an array index

db.collection("users").doc(checkId).update({
    myCart: firebase.firestore.FieldValue.arrayUnion({
        qty: firebase.firestore.FieldValue.increment(1),
    }),
});

and this results to the following error:

Uncaught (in promise) FirebaseError: Function FieldValue.arrayUnion() called with invalid data. FieldValue.increment() can only be used with update() and set()

4 Answers 4

8

My answer below won't work, given that the qty is in an array. The only way to update an item in an array is to read the entire document, update the item in the array, and then write the entire array with the updated item back to the document.


An alternative would be to use a map instead of an array, and then update the qty using the approach outlined in my (old, and non-working) answer below 👇

You need to specify the full path to the field you're trying to update. So I think in your case, that'll be:

db.collection("users").doc(checkId).update({
  "myCart.0.qty": firebase.firestore.FieldValue.increment(1)
}),
Sign up to request clarification or add additional context in comments.

1 Comment

Sir this is overwriting all the values in " myCart.0 " with qty:1 , I just want to increment that qty only
6

The field you want to update is embedded in an array. In this case, you can't use FieldValue.increment(), since it's not possible to call out an array element as a named field value.

What you'll have to do instead is read the entire document, modify the field in memory to contain what you want, and update the field back into the document. Also consider using a transaction for this if you need to update to be atomic.

(If the field wasn't part of an array, you could use FieldValue.increment().)

2 Comments

Ok Understood Thank uh
Use dot notation like the answer given by Coder Marine below suggests. Way easier
2

As of today (29-04-2020)... this is tested by me.

Suppose my data structure is like this:

collection: Users Any document: say jdfhjksdhfw It has a map like below map name: UserPageVisits map fields: field1,field2,field3 etc

Now we can increment the number field in the map like below:

mapname.field1 etc...

That is use the dot operator to access the fields inside the map just like you would do to an object of javascript.

JAVA Code (Android), update the field using transactions so they can complete atomically.

transaction.update(<documentreference object>,"UserPageVisits.field1",FieldValue.increment(1));

I have just pushed a version of my app which uses this concept and it's working.

Kudos !!

My Best Regards

2 Comments

Thanks! This worked with the Flutter SDK and means I don't have to read the value first, increment and then write. I can just increment directly. Saved me a bunch of reconfiguration work, this should be the accepted answer!
Glad it helped you. :-)
-2

Previous answers helped me as well, but dont forget about the "merge" property!!! Otherwise it will overwrite your entire array, losing other fields.

var myIndex = 0;
const userRef = db.collection('users').doc(checkId);
return userRef.update({
      'myCart.${myIndex}.qty': admin.firestore.FieldValue.increment(1)
    }, {
        merge: true
    });

1 Comment

The .update() method has no { merge: true } option. I believe you are thinking about .set(data, { merge: true})

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.