Difference between set with {merge: true} and update
Solution 1:
The way I understood the difference:
set
withoutmerge
will overwrite a document or create it if it doesn't exist yetset
withmerge
will update fields in the document or create it if it doesn't existsupdate
will update fields but will fail if the document doesn't existcreate
will create the document but fail if the document already exists
There's also a difference in the kind of data you provide to set
and update
.
For set
you always have to provide document-shaped data:
set(
{a: {b: {c: true}}},
{merge: true}
)
With update
you can also use field paths for updating nested values:
update({
'a.b.c': true
})
Solution 2:
Another difference (extending Scarygami's answer) between "set with merge" and "update", is when working with a nested values.
if you have a document structured like this:
{
"friends": {
"friend-uid-1": true,
"friend-uid-2": true,
}
}
and want to add {"friend-uid-3" : true}
using this:
db.collection('users').doc('random-id').set({
"friends": {
"friend-uid-3": true
}
},{merge:true})
will result in this data:
{
"friends": {
"friend-uid-1": true,
"friend-uid-2": true,
"friend-uid-3": true
}
}
however update
using this:
db.collection('users').doc('random-id').update({
"friends": {
"friend-uid-3": true
}
})
will result in this data:
`{
"friends": {
"friend-uid-3": true
}
}`
Solution 3:
Per docs: https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects
Dot notation allows you to update a single nested field without overwriting other nested field. If you update a nested field without dot notation, you will overwrite the entire map field.
As stated above, this replaces entire friends structure.
db.collection('users').doc('random-id').update({
"friends": {
"friend-uid-3": true
}
})
This does not.
db.collection('users').doc('random-id').update({
"friends.friend-uid-3": true
})