How to incrementally apply Immer patch(es) to a firestore doc?

96 Views Asked by At

I have an app that uses Immer for handling state, with patches/inverse patches being used and stored for undo+document history. I would like to use the patches generated by Immer's produce function to update a portion of a Firestore doc, but I cannot find an easy way to do this without writing the different cases out ("add", "replace", "delete", etc) and recursively stitching string names of paths together; it all feels rather clunky. I searched online quite a bit for prior work, but I could only find https://github.com/tdawes/immer-to-firestore, which was last updated 3 years ago, and that being the sole example of exactly what I'm trying to do makes me perhaps there is a reason I cannot find anyone else doing it? Am I missing something?

(Side rant: I asked Bing Chat to help me, and while it missed the entire point of what I was asking, it very cheerfully produced some code that didn't help me at all [sigh]. When I further asked about applying inverse patches, it very enthusiastically and confidently told me we could easily do that too, and proceeded to rename one of the variables in its prior code to "inverse patches", lol.)

I thought it would be easy to find examples of converting Immer patches to update storage like in Firebase. I am currently replacing my entire Firebase doc whenever there is any change, but I'd like to just change the portion of the doc affected by the Immer patch. My code looks like:

setDocument(produce(document,
  (draft) => { 
    draft.newField = "foo" 
  }, 
  (patches, inversePatches) => {
patches.forEach(patch=>{
   console.log(patch); 
   /* here is where I want to update the firestore doc
with firestoreApp.collection("items").doc(document.id).update(data), 
but "data" should be just the portion of the original document
that is affected by the Immer patch */
}
))

// currently I replace the entire document, which seems less than ideal

useEffect(() => {firestoreApp.collection("items").doc(document.id).update(document)},[document])
0

There are 0 best solutions below