3

I want to write a rule that will allow the user to read if and only if the nested child has the userId same as the auth uID

My database structure is as follows

"Chats":{
  "-KDKndo4sg47f7s9":{
    "-KDlmsn4hj4h4jk2n":{
        "fromId"    :  "uid1234n5g3h34g5g5h33j33g4g43h3h3"
        "text"  : "Hi, Can you please help me on this?"
        "toId"  : "uid234553sdfj3n4hjjh3jk3h3jk4k4nm3m3"
    }
  }
}

In this database structure, the -KDKndo4sg47f7s9 is groupId/group key and -KDlmsn4hj4h4jk2n is messageId/message key. Here is my rule

"Chats":{
        "$groupId":{
             ".read": "data.child('$messageId').child('fromId').val() === auth.uid" ,
             ".write":"newData.child('$messageId').child('fromId').val() === auth.uid"        
            }
      }

I tested read access to the rule by using the location /Chats/-KDKndo4sg47f7s9 and userId “uid1234n5g3h34g5g5h33j33g4g43h3h3”

The read and write are always denied. But if I'm writing the rule by passing the key directly as below

"Chats":{
        "$dealId":{
              ".read": "data.child(‘-KDlmsn4hj4h4jk2n’).child('fromId').val() === auth.uid" ,
              ".write":"newData.child(‘-KDlmsn4hj4h4jk2n').child('fromId').val() === auth.uid",        
            }
      }

Both read and write are allowed. In short, I don't want to allow one user to read another user's messages. Please help me on this. Thanks in advance.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Rasitha A K
  • 104
  • 8

1 Answers1

3

This rule is incorrect:

"Chats":{
  "$groupId":{
     ".read": "data.child('$messageId')"

In the third line you have a string '$messageId'. More likely you want it to be data.child($messageId), but that will give a syntax error because $messageId is not defined. Putting $messageId in quotes will remove the syntax error, but now it's just a literal string without the meaning you want.

My best guess is that your database structure means /Chats/$groupId/$messageId, in which case your rules should reflect that:

"Chats":{
  "$groupId":{
    "$messageId":{
       ".read": "data.child($messageId).child('fromId').val() === auth.uid"

With this rule you will be able to read a message if you are the sender.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 1
    Thank you for your answer Frank van Puffelen, but I want to access this path /Chats/$groupId and want to read the messages that have fromId equal to auth.uid. Is that possible? – Rasitha A K Jan 09 '18 at 05:48
  • To read from `/Chats/$groupId` you need to have read permission on that path. This means that security rules cannot be used to filter data. This is known as ["rules are not filters" in the Firebase documentation](https://firebase.google.com/docs/database/security/securing-data#rules_are_not_filters). I recommend that you check out some of the [questions of many developers before you](https://stackoverflow.com/search?tab=votes&q=%5bfirebase%5d%20rules%20are%20not%20filters), including [this original one](http://stackoverflow.com/a/14298525/209103). – Frank van Puffelen Jan 09 '18 at 15:14