Reputation:
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
Reputation: 598728
You seem to have two requirements:
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