10
votes

Can I use the equivalent of array_contains in Firebase Security Rules?

I have an Event class (corresponding to Event documents in the events collection). Each document has a subscribers list/array that contains the UIDs of all the users who should be able to query for this event:

{
    .
    "subscribers" : ["uidA", "uidB", "uidC"],
    .

}

More explicitly, a user should be able to run the query:

db().collection("events").whereArrayContains("subscribers", "uidC");

How do I write this security rule?

I tried:

match/events/{eventId} {
    allow list: if request.auth.uid in resource.data.subscribers;
}

and the simulator tells me that access would be denied.

Using functions like this also reports access denied:

function isSubscriber() {
    return resource.data.subscribers.includes(request.auth.uid);
}

match/events/{eventId} {
    allow list: if isSubscriber();
}
1
Did you try any of this outside the console emulator? It's been known to have some problems.Doug Stevenson
It seems to me that the console can't accurately simulate a list type rule, since it only applies to queries, and you can't do queries in the simulator. Have you tried this with an actual query in a client app, not in the simulator?Doug Stevenson
Haven't tried it outside the console. It doesn't show an error with the syntax, but since I haven't found a similar example in the docs, I don't know if it'll work. I'll give it a shot.markvgti
You were right (thanks!), the rule if request.auth.uid in resource.data.subscribers; actually does work in practice. However, the in operator is undocumented (found it through another SO question). Anywhere I can report this?markvgti
The in operator is documented, as are all list operations: firebase.google.com/docs/reference/rules/rules.ListDoug Stevenson

1 Answers

30
votes

Thanks to the advice of @DougStevenson, I used the rule:

match/events/{eventId} {
    allow list: if request.auth.uid in resource.data.subscribers;
}

and then had my Android dev actually try a query from his device, and it worked!

Don't blindly trust the Firestore Security Rules' simulator, it lies!!!

Firebase security rules documentation: https://firebase.google.com/docs/reference/rules/rules.List (apparently it also applies to Firestore).

(PS: yes, fully aware that Firestore is still in Beta)