I am trying to read a path in my Firebase Realtime database /users/uid1 where the value at the path is null. In effect, it does not exist. My security rules allow reading at the path (rules below). When actually reading data, permission is denied.
Security rules are as follows:
{
"rules": {
"users": {
"$uid": {
".read": "root.child('users').child($uid).child('mUser_Role').child('mRole_PermissionLevel').val() > 400 || root.child('users').child(auth.token.phone_number).child('mUser_Role').child('mRole_PermissionLevel').val() == 500"
}
}
}
}
Trying to read /users/uid1 with /users/myuid/mUser_Role/mRole_PermissionLevel == 500 being true fails with permission denied.
How does Firebase determine that permission should be denied for the case when value is null ? Shouldn't this read be allowed and return a dataSnapshot where dataSnapshot.exists() returns false ?
I have not specified any rules around data at the path being null and the read succeeds when the value at the path is not null
EDIT - To re-produce this scenario -
1. Upload JSON to the root of a Firebase realtime db-
{
"users" : {
"+9198100xxxxx" : {
"mUser_Id" : "+9198100xxxxx",
"mUser_ProfilePicUrl" : "url",
"mUser_Role" : {
"mRole_Name" : "Employee",
"mRole_PermissionLevel" : 500
}
},
"+9198100yyyyy" : {
"mUser_Id" : "+9198100yyyyy",
"mUser_ProfilePicUrl" : "url",
"mUser_Role" : {
"mRole_Name" : "Employee",
"mRole_PermissionLevel" : 500
}
}
}
}
2. Firebase realtime db rules (actually using for this node) -
{
"rules": {
"users": {
"$uid": {
".read": "root.child('users').child($uid).child('mUser_Role').child('mRole_PermissionLevel').val() > 400 || root.child('users').child(auth.token.phone_number).child('mUser_Role').child('mRole_PermissionLevel').val() == 500"
}
}
}
}
3. Use Firbease security rules simulator -
Simulation type - read
Location - /users/+9198100zzzzz (simulated read fails)
Location - /users/+9198100yyyyy (simulated read succeeds)
Authenticated - yes
Provider - custom
Auth token payload -
{
"provider": "phoneauth",
"uid": "6f2eed52-b2e9-409a-b5f1-dc307c7f6671",
"token":{
"phone_number": "+9198100xxxxx"
}
}


auth.token.phone_numberin your rule instead ofauth.uid. Is that intentional? Your question suggests you want to use the uid in the path, and says nothing about phone number. - Doug Stevensonauth.token.phone_numberin the rule. The user IDs in the database are the same as phone numbers. Also, I am using phone authentication. My security rule gets thephone_numberfrom theauth.tokenin the request, then checks the permission level at the path corresponding to that user ID in the database (where user ID is same asphone_number).Hence the path in the rule. I am not usingauth.uidas a user ID in the database @FrankvanPuffelen Thanks. I'll get back with this as soon as I can - Kartik