I have an app running with a Firebase realtime DB.
Broadly speaking I have a couple of nodes:
- users (containing user info like uid, name and "role" - which can be "user" or "admin")
- private data (containing various stuff each user can enter for themselves, not deeply private stuff)
I'm attempting to set up an admin interface, in which the "admin" (so marked in the users table) can also see the data in the private area of everyone else.
I looked at an example here which contains a line like this (where isAdmin is a boolean field):
"rules": {
"users": {
"$uid": {
".read": "auth.uid == $uid || root.child('users').child(auth.uid).child('isAdmin').val() == true",
".write": "root.child('users').child(auth.uid).child('isAdmin').val() == true",
".indexOn": ["email"]
}
}
}
So I have a rule
{
"users": {
".indexOn": ["uid", "username", "role"],
".read": true,
".write": "auth.uid != null",
"$uid": {
".validate": "$uid == auth.uid && newData.hasChildren(['uid', 'username', 'role'])",
"uid": { ".validate": "newData.val() == $uid" },
"username": { ".validate": "newData.val().matches(/^[a-zA-Z0-9.]*$/)" },
"role": { ".validate": "newData.isString()" }
}
},
"privateData": {
"$uid": {
".indexOn": ["name"],
".read": "auth.uid != null && ($uid == auth.uid || root.child('users').child(auth.uid).child('role').val() == 'admin')",
".write": "auth.uid != null && ($uid == auth.uid || root.child('users').child(auth.uid).child('role').val() == 'admin')",
}
}
}
...but my rule doesn't work at all. If I am logged in as me (and of course, mr tole is 'admin' in the users table so I am an admin) I still get errors like this:
core.js:5847 ERROR Error: Uncaught (in promise): Error: permission_denied at /privateData: Client doesn't have permission to access the desired data.
Is there any way to debug this more? I'll happily add info if you tell me what I am missing.
According to this answer (if I understand correctly, I might not) I don't need to have any kind of security like this and I should just have rules like:
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
Is that reasonable? Will it be ok to stop unauthorized folks from seeing other people's private info?
Thanks