Update data in cloud firestore:{merge:true} in set() operation

Mahi!
feedflood
Published in
2 min readMar 10, 2020

So I faced an issue where every time I upload a data set, If the some or all of the documents that I upload already exist in my collection then instead of overwriting It just created new documents so there was redundancy everywhere.

The Usual fix that came to my mind was to give a unique DocID to each document instead of using auto-generated IDs so that if the same doc is uploaded again then DocID will be the same so there will be no duplicacy of data. As expected the solution did actually work but…. I was still overwriting the existing document because of how set() works.

Now the next solution was to use the update() operation instead of set() since it does what it’s called, update a document but……there are some problems in using update() too.

Here’s an example that I found searching for the problem:

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 update()

db.collection('users').doc('random-id').update({ "friends": { "friend-uid-3": true } })

will result in this data:

{
"friends": {
"friend-uid-3": true
}
}`

It simply overwrote the previous values 😲

But we all know that is now how update() is supposed to work right? Right because here we’re not using update() correctly. Actually You have to use a dot notation for updating nested fields. If you update a nested field without dot notation, you will overwrite the entire map field.

So using update() for nested fields should be done like this

db.collection('users').doc('random-id').update({
"friends.friend-uid-3": true
})

This will not overwrite the data and the result will be:

{
"friends": {
"friend-uid-1": true,
"friend-uid-2": true,
"friend-uid-3": true
}
}

So this was all nice and good but that is not what the Title of the post says it’ll teach right?

OK then, here’s another method that you can use to kind of update the data.

{merge:true} can be used as a second parameter to set() and it’ll update the document just like how update() will do and it won’t even need the dot notation to do that.

To use merge you need to pass it like this inside set()

db.collection(‘col-id’).doc(‘doc-id’).set({data},{merge:true})

so by using this method if we again try our example then

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
}
}

And one more thing is that even if your document doesn’t exist then this way the document will be created since we’re using set() here. Which is not possible in the case of update()

Reference: https://stackoverflow.com/questions/46597327/difference-between-set-with-merge-true-and-update

If you like my work please consider supporting me

Thanks:)

--

--