3
votes

I'm using firebase and my users are set up like this:

{
    "firebase-account-123": {
        "users": {
            "simplelogin:1": {
                "properties"{ "name": "john doe", "email": "[email protected]" }
                "children": {
                    "simplelogin:2":{ "name": "user 2", "email": "[email protected]" },
                }
            },
            "simplelogin:2": {
                "properties"{ "name": "user 2", "email": "[email protected]", "disabled": false }
            }
        }
}

I have "children" which account managers should have access to. I'm new to this and I'm trying to solve some permissions problems I'm having.

My rules currently only allowing the users to read/write their own data.

".read": "auth.uid == $userid", ".write": "auth.uid == $userid"

Does anyone know how I could make it so they also have the ability to write/read data (maybe just in the properties object) for users that are listed in their "children" object?

2
Most likely, this structure won't scale well, based on what I've seen as common usage. You may want to consider moving "children" to a separate path as it's most likely a separate logical component (i.e. the list of people I manage). Security rules and iterating data will probably be much simpler if they are in their own paths.Kato

2 Answers

4
votes

If you want to allow the user-ids listed under the children bucket to read and write data as well, try using the hasChild() method in your security rules.

For example, using the same data structure that you outlined above:

{
  "rules": {
    ".read": false,
    ".write": false,
    "users": {
      "$userid": {
        ".read": "auth.uid == $userid",
        ".write": "auth.uid == $userid",
        "properties": {
          ".read": "root.child('users').child(auth.uid).child('children').hasChild($userid)"
        }
      }
    }
  }
}
3
votes

Something like this should do the trick:

".read": "auth.uid == $userid || root.child('users/'+auth.uid+'/children/'+$userid).exists()"

So this grants access to a node when:

  • it is the currently logged on user's own node
  • the currently logged on user has a child node with the node's id

I would recommend cleaning up your data structure a bit to remove the duplicate data in the children:

{
    "firebase-account-123": {
        "users": {
            "simplelogin:1": {
                "properties"{ "name": "john doe", "email": "[email protected]" }
                "children": {
                    "simplelogin:2": true
                }
            },
            "simplelogin:2": {
                "properties"{ "name": "user 2", "email": "[email protected]", "disabled": false }
            }
        }
}