Search code examples
androidfirebasefirebase-realtime-databasefirebase-securityrule

How to set firebase read rule and read all siblings if one matches


I have set my firebase rules as follows:

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

    }}
  }
}

Which allows write only to the node with matching uid and read all child nodes of every uid. But I want it to be like if I query using a child node under uid, only the matching child and it's siblings can be read...

for example this is my json structure:

 {
"users" : {

      "AJkK4yZJsoseeefrJ7i6KIOUBDghtrhgthrtDi1" : {
        "lat" : 20.5001,
        "long" : 68.3755,
        "number" : "9876543210",
        "time" : 1499599788090
      }
    }
}

I want to query using the number, and set the read rule as can read lat long and time only where the number matches. How to write the rule?

update: my question now is, how to query the database using number and get other siblings if value of number matches in android? I have tried this but not working:}

  friend = mDatabase.getReference("users");
  friend.keepSynced(true);


  Query z = LocationActivity.this.friend.orderByChild("number").equalTo("9876054321");

  z.addListenerForSingleValueEvent((new ValueEventListener() {
        long lastseen;
        public void onDataChange(DataSnapshot dataSnapshot) {
            try {
                for (DataSnapshot zoneSnapshot: dataSnapshot.getChildren()) {
                    lastseen = (Long)zoneSnapshot.child("time").getValue();
                    friendLatitude = (Double) zoneSnapshot.child("lat").getValue();
                    friendLongitude = (Double) zoneSnapshot.child("long").getValue();
                }


            } catch (Exception e) {
            }}

it returns value null, any help would be appreciated.


Solution

  • Firebase read permissions are enforced when you attach a listener. In order to query a node, you must have read permission on that node (as Bradley also explained). So in order to be able to query users, you must have read permission on /users. And since any user that has read permission to /users can also read any data under that, you cannot use security rules to filter what nodes a user has access to.

    This is known as rules are not filters and is one of the common pitfalls for developers new to Firebase security model. I recommend that you read the documentation I linked already and some of the many questions/answer about the topic.

    The simplest solution for your use-case seem to be to pull up the .read rule to users:

    {
      "rules": {
        "users": {
          ".read": "auth != null",
          "$uid": {
            ".write": "$uid === auth.uid"
          }
        }
      }
    }
    

    }