firebasegoogle-cloud-firestoreangular6

Difference between merge and mergeFields in Firebase Firestore


I can a data to the Firebase Firestore document through the following methods:

1) add()

2) set()

I am very clear that how can i add data to Firestore, there is no confusion in it. But my question there is two setOption for the method 'set' in Firebase Firestore, such that merge and mergefields. What is the difference between these two set options, I think both options are doing same job. How can I implement setOption 'mergeFIeld'? I can't find any documentation for it.


Solution

  • As you already noticed, when using DocumentReference's set() function, you are allowed to pass as the second argument either SetOptions's merge:

    Changes the behavior of a set() call to only replace the values specified in its data argument. Fields omitted from the set() call remain untouched.

    Or SetOptions's mergefields:

    Changes the behavior of set() calls to only replace the specified field paths. Any field path that is not specified is ignored and remains untouched.

    Both are optional, but both change set to act as a Merge/Upsert instead of overwriting all fields not provided in the data parameter. This will create the document from the document reference if it does not exist, and otherwise performs the behavior of update.

    SetOptions.Merge will merge based on the object keys you specify in its data parameter. SetOptions.MergeFields is a bit more awkward. It's easy to skim right over the documentation description, but it states that the array of field paths you specify will be the only ones taken from the data parameter when updating values. Meaning not all the key-values passed in the data parameter are used in the merge operation.

    Think of mergeFields as picking key-values from the provided data and applying those in your operation. It's not really necessary, and just is a shorthand for cleaning up the key values and passing into merge. Note, it will not delete fields omitted in data that are declared in the field path array, instead you just get a firebase error that a field path is missing from your input data. It seems like explicit FieldValue.delete is the only option for that behavior.

    For nested field paths you do get some additional benefit. You can more explicitly control the update operation.

    ex. For document name: { first: 'Jon', last: 'Doe' }


    set({ name: { first: 'Jane' } }, { merge: true });

    becomes

    name: { first: 'Jane', last: 'Doe' }


    set({ name: { first: 'larry' } }, { mergeFields: ['name.first'] })

    also becomes

    name: { first: 'Jane', last: 'Doe' }


    set({ name: { first: 'larry' } }, { mergeFields: ['name'] })

    unlike the others becomes

    name: { first: 'Jon' }

    where the field path is replaced.