Search code examples
firebasefirebase-realtime-databasefirebase-security

Firebase Realtime Rules: Split users into multiple groups w/ role-based (token) authentication


Each user is authenticated w/ a token of state and city.

I want the users to be able to read data at /data/$state, /data/$state/$city

For /data/$state/$city I can add a rule (on /data/$state/$city): .read: $state == auth.token.state && $city == auth.token.city",

This would work well, how ever to grant access to /data/$state access I would write (on /data/$state): .read: $state == auth.token.state",

Which would grant read access down the line to any node in any city (in the state, /data/$state/*) and ignore the previous one (based on Firebase Realtime rules where top rules takes precedence).

Do I have any way to handle this beside flattening my data into:

/Cities/$state/$city

/States/$state

Thus handling security for each case in their respective node?

Thanks!


Solution

  • No, as explained in the doc, it is not possible:

    .read and .write rules work from top-down, with shallower rules overriding deeper rules.

    ...

    Shallower security rules override rules at deeper paths. Child rules can only grant additional privileges to what parent nodes have already declared. They cannot revoke a read or write privilege.


    So you indeed need to denormalize your data as mentioned at the end of your question. Note that the update() method allows to easily write to different nodes, see the example in the doc.