Jacob Kizzee
Jacob Kizzee

Reputation: 41

Firebase - User Based Rule Access On Another Path

I'm looking to allow read access to a device list in firebase only if a user has this device id listed under their account.

As recommended by Anant in his answer found here: Security Rules - lists of data that can be read? I implemented this firebase data structure:

{ 
  devices: { 
    111: {status: 10}, 
    222: {status: 5}
  }, 
  users:  {
    aaa: { 
      name: 'Jim', 
      devices: { 
        111: {name: 'Test Device'}
      } 
    } 
    bbb: { 
      name: 'Jane', 
      devices: { 
        111: {name: 'Test Device'},
        222: {name: 'New Device'}
      } 
    } 
  }
}

To clarify the outputs, User "aaa" named Jim should only be able to read device id "111" from the device list and get it's children elements. User "bbb" named Jane can see both devices "111" and "222" and their children elements

So I implemented several rules trials and ended with the following:

{
    "rules": {
        "users":{
          "$user_id":{
            ".read": "auth.uid == $user_id",
            "devices": {
              "$devices_id":{
                ".read":true
              }
            }
          }
        },
        "devices":{          
          "$devices_id":{
            ".read": "root.child('users').child(auth.uid).child('devices').hasChild('$devices_id')",
            ".write": false
          }
        }
    }
}

When reading device data this rule should look at the /root/users//devices/$devices_id and see if that device_id exists under the user making the request. Then allow read access to that record. According to the post linked above this should be possible, but the post does not express what permissions should be set for the main list of "conversations" (devices in my case)...Anant only says "Make sure to set the permissions on the top-level conversations list appropriately". Can someone clarify how to do this?

I only get permission denied for these requests under the rules above. I have also tried: "root.child('users').child(auth.uid).child('devices').child('$devices_id').exists()" And this does not work either...

Any guidance on this process would be greatly appreciated. I am also open to other data structures and rules structures that make this happen. It is a fresh project and very modifiable at this stage.

Thanks!

Upvotes: 0

Views: 208

Answers (1)

Jacob Kizzee
Jacob Kizzee

Reputation: 41

Thanks to @Kato! The implementation above is correct except for the string literal surrounding $device_id.

Changing

.hasChild('$devices_id')

To

.hasChild($devices_id)

Fixed the problem and allowed only the assigned devices under a user to be readable from the top level devices structure.

Upvotes: 1

Related Questions