I have notification records where there is a text and a list of users (max 10).
{text: \"Beware of the dog\", users: [ uid1, uid2, uid3, ... ]}
I don't think this is possible without a loop, which doesn't exist in security rules. Well: if you know all users, you might be able to enumerate all options, essentially unfolding the impossible loop. But even if this is possible in security rules, the rules are going to be incredibly verbose.
I'd recommend creating a subcollection where each UID is stored in a separate document. In that subcollection you can then implement your requirement by only allowing the user to only delete their own document.
I had a similar situation and it was quite a brain teaser. This is what did the trick for me:
allow update: if
request.auth.uid != null
&& request.resource.data.diff(resource.data).affectedKeys().hasOnly([data])
&& request.resource.data.users.size() == resource.data.users.size() - 1
&& resource.data.users.removeAll(request.resource.data.users)[0] == request.auth.uid
Specifically:
data
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.