I would like to implement "write" security rules in Firebase depending on users roles.
My data structure is like this:
+ myapp
+ users
+ john
+ email: "[email protected]"
+ roles
+ administrator: true
+ mary
+ email: "[email protected]"
+ roles
+ moderator: true
+ ...
+ documents
+ -JVmo6wZM35ZQr0K9tJu
+ ...
+ -JVr56hVTZxlAI5AgUaS
+ ...
+ ...
I want - for example - that only administrator users can write documents.
These are the rules I've come to:
{
"rules": {
".read": true,
"$documents": {
".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true"
}
}
}
But it doesn't work: not even administrator users can write documents...
Is my understanding of Firebase security rules totally flawed?
UPDATE:
Just before Jenny's answer (believe it or not :-), I did implement the exact same solution he provides (of course based on Kato's comment).
Though, making some tests, I could not let the rules structure
{
"rules": {
"documents" {
"$document" {
".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
}
}
}
}
work... I always got a warning like this:
"FIREBASE WARNING: on() or once() for /documents failed: Error: permission_denied: Client doesn't have permission to access the desired data. "
So I came up with this structure, instead:
{
"rules": {
"documents" {
".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
}
}
}
Which indeed works, for me: if I set a roles/customers/read node to true on a user he can read all documents, otherwise he can't (and the same for write).
My doubts now are:
- why I could not let the first rule (as suggested by Kato) work?
- do you see any possible security hole in a rule like the one I did came up with?
- are rules using "$" variables necessary/useful even if you don't have to allow/deny the readability/writeability of each single document based on it's key, but you just want to allow/deny the readability/writeability of a node as a whole?
twitter:2544215
). Also, your.write
rule should probably be under documents/$document instead of $documents (off of root), otherwise you'll be allowing access to any path on root. – Kato