Home > database >  Firestore rule to only add/remove one item of array
Firestore rule to only add/remove one item of array

Time:10-23

To optimize usage, I have a Firestore collection with only one document, consisting in a single field, which is an array of strings. The client app will retrieve that array, pick one string at random and then submit the updated array without the one it picked. Once it tries to use the string that it picked, the app can either succeed or fail. If it succeeds, there's nothing left to be done, but if it fails, it needs to put the string back into the same document field in Firestore. Is there a way to express in Firebase rules that the submitted array should be the same as what was there before except for one item?

Later edit: It might be easier to have all the strings as separate fields within the same document, in which case I would need to specify that only one field can be removed/added per write.

Even later edit: I can just make the list of all strings read-only and allow the users to write in a separate collection the one they picked at random. I'd still want to limit the write capabilities to a single document and maybe even validate the format of that document in some way.

CodePudding user response:

You can use the methods associated with the Set object.

Here is an example to check that only 1 item was removed:

allow update: if checkremoveonlyoneitem()

function checkremoveonlyoneitem() {
  let set = resource.data.array.toSet();
  let setafter = request.resource.data.array.toSet();
  return set.size() == setafter.size()   1
    && set.intersection(setafter).size() == 1;
}

Then you can check that only one item was added. And you should also add additional checks in case the array does not exist on your doc.

CodePudding user response:

If you are not sure about how the app performs the task i.e., successfully or not, then I guess it is nice idea to implement this logic in the client code. You can just make a simple conditional block which deletes the field from the document if the operation succeeds, either due to offline condition or any other issue. You can find the following sample from the following document regarding how to do it. Like this, with just one write you can delete the field which the user picks without updating the whole document.

city_ref = db.collection(u'cities').document(u'BJ')
city_ref.update({
    u'capital': firestore.DELETE_FIELD
})snippets.py

  • Related