Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore rules: Check which array element is removed

Is it possible to check which element of a document array is requested to be removed/added?

like image 223
ktm125 Avatar asked Oct 27 '18 18:10

ktm125


2 Answers

UPDATE 2020

You now actually can check for a removed item. All you have to do is subtract the new, reduced, array from the old one with removeAll() and check the items of the array that it returns.

For example to allow only the removal one's own uid from an array, you would do:

allow update: if 
    request.auth.uid != null 
    && request.resource.data.users.size() == resource.data.users.size() - 1
    && resource.data.users.removeAll(request.resource.data.users)[0] == request.auth.uid

Specifically:

  1. The first rule checks for user authentication
  2. The second rule makes sure that the new array is exactly 1 item shorter than the old one (so that only 1 item can be removed at a time)
  3. The third rule subtracts the new array (now reduced by 1 uid) from the old one with removeAll() and returns an array with their difference. In this case, it returns an array which contains only the single uid that you chose to arrayRemove(). Then we simply check that uid - which can only exist at position [0] - and make sure it is equal to the uid of the authenticated user.
like image 179
Konstantinos T. Avatar answered Oct 30 '22 10:10

Konstantinos T.


As you probably noticed, queries in Cloud Firestore are very fast and this is because Firestore automatically creates an indexes for any fields you have in your document.

There are many posts out there that say that arrays don't work well on Cloud Firestore because when you have data that can be altered by multiple clients, it's very easy to get confused because you cannot know what is happening and on which particular field. If you're using a Map and users want to edit several different fields, even the exact same field, we generally know what is happening. In an arrays, things are different. Try to think what might happen if a user wants to edit a value at index 0, some other user wants to delete the value at index 0 and in the same time another user wants to add another value at index 1, you'll end up having very different results and why not, an ArrayIndexOutOfBoundsException. So Firestore actions with arrays are a little bit different. So you cannot perform actions like, insert, update or delete at a specific index. So use arrays only if don't care about the exact order that you store elements. Firestore added a few days ago some features to add or remove specific elements but only if don't care about the exact position of them. See here official documentation.

And to answer to your question:

Is it possible to check which element of a document array is requested to be removed/added?

No, you cannot!

like image 30
Alex Mamo Avatar answered Oct 30 '22 10:10

Alex Mamo