Skip to content

Firestore Security Rules: use array_contains to determine authorization

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();
}

Answer

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 can differ from reality!!! The code for the simulator is probably different than the code that is deployed for actually evaluating rules in production, so the results may differ slightly.

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