user9559682
user9559682

Reputation:

Firebase security rule with read and write at separate locations

I have my Realtime database schema designed like this.

"roles" : {
    "uid-1" : "user",
    "uid-2" : "moderator",
    "uid-3" : "user" // ... and so on
}

"photos" : {
    "uid-1" : {    
        "photo" : "..."
        "date" : "..."
    }
    // ... and so on
}

And my security rules are defined like this. Only relevant part is shown.

"photos" : {
    "$key" : {
        ".read" : "auth.uid == $key || root.child('roles/'+auth.uid).val() == 'moderator'",
        ".write" : "auth.uid == $key"
    }
}

As it is clear from the above snippet I want the users to be able to read or write to their own key under photos node. As for the moderators I want them to be able to read any users data.

At first it seems to work as expected but there is a small catch. According to fire-base if no rule is specified at a node it will be considered as false. That means moderator can now read every users data but only if he explicitly asks for certain UID. In other words reading photos/<uid> is allowed but photos/ as a whole is not allowed.

A potential solution was to move read statement to make it direct child of photos node. But there I cant enforce $key for other users.

One might try to split the rule and define at both locations but that would not work because according to firebase docs shallow rules will override the deeper rules.

Upvotes: 0

Views: 144

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

You seem to have two requirements:

  1. Each user can read and write their own photos.
  2. A moderator can read photos of all users.

That can be enforced in server-side security rules like this:

"photos" : {
    ".read" : "root.child('roles/'+auth.uid).val() == 'moderator'",
    "$key" : {
        ".read" : "auth.uid == $key",
        ".write" : "auth.uid == $key"
    }
}

The permission that an moderator gets from /photos carries down onto each user's photos. This permission cannot be revoked at a lower level. But you can definitely give users *additional** permission at a lower level, which is what these rules do.

Upvotes: 1

Related Questions