0

I am struggling with the security rules on the firebase realtime database. My database structure is as following:

Database Structure

On the first level you have Chats. On the second level there are the Chat partners (a concatenated string with user IDs of chat partners). On the third level you have the messages. And on the last level there are the variables datetime, userid and message.

My question is, how can I get into the second child node, e.g. check if the auth.uid is within the concataneted string. My idea was to give the users read access, if the userid is within the chatpartners string, to ensure that only the chatpartners can read their messages. Or is this a thinking error? I have tryid a lot of things, however no success:

"Chats":{
   ".read": "root.child('Chats').val().contains('auth.uid')"    
 }

#Update

{
 "rules": {
   "Chats": {
     "$chatid": {
      ".read": "$chatid.contains(auth.uid)",
      ".write": "auth != null"
      }
   },
   "Suchencards": {
      ".read": "true",
            ".write": "auth != null"
   },
   "UserData": {
     "$uid": {
      ".read": "$uid === auth.uid",
            ".write": "$uid === auth.uid"
     }
   }
 }
}

I am using the playground on firebase console to check if I get true or false, however in that case I get false.

#Update 2

Screen1

Screen2

bonus
  • 1
  • 3

1 Answers1

0

You can only access data in your rules if you know the exact path to that data, so you won't be able to access all chats from a rule on /Chats. Trying to do so typically means that you're trying to define your rules on the wrong level.

For example, if you want to allow a user to read a specific child of Chats, you'll need to define rules on that level:

"Chats":{
  "$chatid": {
    ".read": "$chatid.contains(auth.uid)"
  }
}

While the above will work for accessing a specific room, you will not be able to use this to query for all chat rooms that a user has access to (as Firebase queries don't support a "contains" operation). Have a look at the userChatrooms node in my answer here for a better model for tracking the chat rooms for a user: Best way to manage Chat channels in Firebase

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanks Frank! Tried that code chunk you have provided with the wildcard solution $chatid.contains(). I put auth.uid into contains as well as the whole concataneted string. Both gives me a false, not a true, althoug the concataneted string is in the database. – bonus Jan 04 '22 at 17:58
  • Can you update your question to show the updated rules, and the minimal code that reproduces the problem (as rules don't do anything on their own)? – Frank van Puffelen Jan 04 '22 at 19:26
  • Okay just edited/updated my post. – bonus Jan 05 '22 at 11:44
  • You're trying to read `/Chats/chatid` in those screenshots, which means that `$chatid` is `"chatid"` and doesn't contain the UID you used. To make it work, read a path that includes the UID. – Frank van Puffelen Jan 05 '22 at 22:59
  • Thanks Frank. It works fine, when reading the correct path, however something goes wrong when trying that on the device. Will check it. – bonus Jan 07 '22 at 20:08