0

I have a problem with Firebase rules. Basically I have a root folder called 'users', containing many usersIDs that again contains data, exactly like this:

users {
    userid1 {
        info_user {
            a: {
                a1: whatever
                a2: whatever       
                a3: {
                    a3.1: whatever
                    a3.2: whatever
                    a3.3: whatever
                    a3.n: whatever
                }
            }
            n: {} ...
        }
    },
    userid2 {}, ...n
}

Everything work fine when running the following code if there is no security rules, such:

{rules {".read"  : true, ".write" : true}}

function getUserInfo () {
    var dbRef = firebase.database();
    var myArray = [];
    dbRef.ref('users').on('child_added', function(snapshot) {
        snapshot.forEach(function(childSnapshot) {
            myArray = (childSnapshot.val().a3);
            // do something
        });
    });
}

My challenge is to change the security rules without change the database structure.

So, I tried to do something like this:

{
    "rules" : {
        ".read"  : false,
        ".write" : false,
        "users": {
            "$userid": {
                "info_user": {
                    "a":{
                        ".read": "auth != null",
                        ".write": "(root.child('r').child('w').hasChild(auth.uid))",
                        "a1":{".validate": "newData.isString()"},
                        "a2":{".validate": "newData.isString()"},
                        "a3":{".validate": "newData.isString()"}
                    },
                    "n": {
                        ".read": "auth != null",
                        ".write": "$user_id === auth.uid"
                    }
                }
            }
        }
    }
}

The expected result is to read a node a3 when user is authenticated.

How to do this?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
hbbz040
  • 184
  • 1
  • 1
  • 16

1 Answers1

2

Firebase Database read permission is enforced when you first attach a listener. So when you attach a listener to dbRef.ref('users'), you must have read permission to /users. In your security rules that is not the case.

To make the rules work, move the read permission up to `users:

{
  "rules" : {
    "users": {
      ".read"  : "auth != null",
      ...

Note that permission cascades down. So once you grant the user read permission on /users, they have access to all data under /users. You cannot take this permission away for a specific node under there.

This leads to one of the pitfalls of securing your Firebase Database: rules cannot be used to filter data. For more on this, see the Firebase documentation on "rules are not filters", this answer about it and many more of the questions from developers struggling with the concept.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807