0

I have a Firestore document that contains an array of objects (user-defined email templates). I want to delete an object based on its name. (The idea is that when the user adds a new email template if it has the same name as an existing object, it is deleted and added again, basically updated. But if the name does not exist in the array, it is just added as a new template).

enter image description here

I have read these similar posts, but they are old and seem to refer only to simple arrays of strings, not objects.

How to delete object from array in firestore

how to add or remove item to the the existing array in firestore ?

I have tried of course with ArrayRemove but it doesn't work. The console.logs before and after a run, but nothing is removed from Firestore.

//this either 
// 1. (if the template with this name is found): adds a new email template to the list in the User doc
// or 2. (if no template with the same name is found): deletes the template with the same name and adds the new template
const saveNewTemplateExternal = () => {

  const nameininput = store.state.currentEmailTemplate.name

  const alltemplates = store.state.userData.emailtemplates
  let index = -1
  if (alltemplates) {
    index = alltemplates.findIndex(object => {
      return object.name === nameininput;
    });

  }



  if (index > -1) {
    alert('found a match')
    let templateRef = doc(db, "users", store.state.userData.id)
    console.log("will now remove: " + alltemplates[index].name + " : " + alltemplates[index].body)

    updateDoc(templateRef, {
        emailtemplates: arrayRemove(alltemplates[index])
      })
      .then(() => {
        console.log("removed: " + alltemplates[index].name + " : " + alltemplates[index].body)
      })
  }


  //use current timestamp as id
  store.state.currentEmailTemplate.id = Date.now()

  let templateRef = doc(db, "users", store.state.userData.id)
  updateDoc(templateRef, {
    emailtemplates: arrayUnion(store.state.currentEmailTemplate)
  })

}

After this function executes, I am left with the old and the new object in Firestore.

Thanks for any help!!

Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
jeff3546
  • 175
  • 11
  • 1
    If none of the answers seem to be working, please `console.log(alltemplates[index])` and share a screenshot of both the logged output and your Firestore document. – Dharmaraj Oct 04 '22 at 10:05

1 Answers1

0

The solution that exists in one of the linked answers:

docRef.update({
   array: FieldValue.arrayRemove('idToRemove');
});

Works only if the elements in the array are strings. The emailtemplates array that exists in the shared document, it's not an array of strings, but an array of custom objects. That being said, to be able to remove a particular object, you have to pass to the arrayRemove() function the entire object. It does not work with partial data. So something like this will not remove the first object from the array:

docRef.update({
   emailtemplates: FieldValue.arrayRemove('obj1');
});

Alternatively, you can:

  1. Read the document in memory.
  2. Remove the needed object.
  3. Write the document back to Firestore.
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Thank you! I see your point in having to pass the entire object to arrayRemove(), but that is what I am doing already: arrayRemove(alltemplates[index]) where alltemplates[index] is the object. – jeff3546 Oct 04 '22 at 10:04
  • Are you sure it's the [exact same object](https://stackoverflow.com/questions/71033454/flutter-how-can-use-fieldvalue-arrayremove)? Otherwise it will **not** work. – Alex Mamo Oct 04 '22 at 10:07
  • 1
    As far as I can see yes, but I must have overlooked something. I realised it would be much simpler with a subcollection in the end. Thank you! – jeff3546 Oct 04 '22 at 10:13
  • It's a trick and Good, But not the official solution from google. I think Google should provide the actual solution of this problems. – umesh kumar bedi Apr 07 '23 at 09:14