2

In firestore documentation it says that merge: true is needed if we want to merge data, it doesn't work

Here is my code, which is very similar to the example, it always replaces the old stored value ​​with the new one

async function updateTotal() {
  const update = await db.collection("resources").doc(id).update({ "total": "500"}, { merge: true })
}

I really need it if you have a solution please

busooCombo
  • 51
  • 4
  • The `merge` option works by combining the data already in the document with the data you are sending in your update. If your document already has data and you send an update without `merge` enabled, it will replace all of the fields in the document with the ones that you sent. If you send an update with `merge` enabled, it will try to combine the existing data in the document with the fields that were present in the update. `merge` will not store the historical changes of a document, it simply allows you to add/update the fields on a document without needing all of the original data. – nick-w-nick Jun 27 '22 at 18:35
  • I understood it well, in my firestore I have "total": "1500", and with my example above I merge "total": "500", Since the data already exists and it's both a Number, shouldn't that put me "total": "2000" in my firestore? – busooCombo Jun 27 '22 at 19:00
  • Unfortunately that is not how the `merge` option works. It simply allows you to add/edit specific fields in a document without affecting the others. If you had a document with these fields: `{"name": "john", "total": "1500"}` and sent an update of `{"total": "500"}` with `merge` set to `false`, you would end up with a document of only `{"total": "500"}`. The `name` field was removed because you sent an update without `name` while `merge` was disabled. If you sent an update of `{"total": "500"}` with `merge` enabled, you would end up with `{"name": "john", "total": "500"}`. – nick-w-nick Jun 27 '22 at 19:26
  • @busooCombo Did you have a chance to check out my [answer](https://stackoverflow.com/a/72792834/13171940)? – Rogelio Monter Jul 04 '22 at 15:46

1 Answers1

1

As shown on this other answer:

  • set merge will always override the data with the data you pass, while
  • update is specifically designed to give you the possibility to perform a partial update of a document without the possibility of creating incomplete documents that your code isn't otherwise prepared to handle. Please check this answer, as well as this scenario.

This is what nick-w-nick explains in his comment.

This another answer explains better the use case for each option:

  • set without merge will overwrite a document or create it if it doesn't exist yet
  • set with merge will update fields in the document or create it if it doesn't exists
  • update will update fields but will fail if the document doesn't exist
  • create will create the document but fail if the document already exists

For the expected result you explained in your comment, you should be using an increment operation, as follows:

You can increment or decrement a numeric field value as shown in the following example. An increment operation increases or decreases the current value of a field by the given amount.

// Atomically increment the population of the city by 50.  
washingtonRef.update({ 
   population: firebase.firestore.FieldValue.increment(50)  
});

See also:

Rogelio Monter
  • 1,084
  • 7
  • 18
  • Sorry I had not seen your message, your explanation is very clear and I thank you for it. Your section on incrementation interests me enormously. I'm going to try that this weekend and get back to you! – busooCombo Jul 07 '22 at 21:49