0

In my app, I don't want a user that has been blocked by another user, to find such user. Let's say, user1 has blocked user2. When user2 then searches through all the users within the app, I want user2 to find every user except user1, because user1 has blocked user2. It's like with Instagram, when you block someone that someone cannot interact with you in any way. I have stored the users in the realtime database like so:

users
|-user2(uid)
   |-blocks
       |-user1(uid): 1
   |-email: String
   |-id: String(the uid)
   |-fcm: String
   |-name: String
   |-profileImage: String
   |-username: String

I am trying to prevent user2 from interacting with user1 with these Firebase rules:

{
"rules": {
  "users": {
    "$uid": {
".read": "auth != null && !(root.child('users').child(auth.uid).child('blocks').hasChild($uid) != true)",
".write": "auth != null"
}
},
  "posts": {
    "$postId": {
      ".read": "auth != null",
        ".write": "auth != null"
    }
  }
}
}

user2 cannot see user1 anymore when going through another user's followers list, although user1 is in that list. So the security rules work there. But now, none of the users within my app can look for any other user anymore, because as soon as the search is activated, my console says this:

[Firebase/Database][I-RDxx0xxxxx] Listener at /users failed: permission_denied

At every other "window" like feed or other user's followers list the console says this:

[Firebase/Database][I-RxxBxxxxxx] Listener at /users/user1 failed: permission_denied

This shows, that it is somewhat working, because only for user1 the permission was denied.

So what is the mistake?

JuFa512
  • 119
  • 7
  • Hi @FrankvanPuffelen, I have made progress on this. Your answer was not my final solution. I have posted the solution here: [link](https://stackoverflow.com/questions/69305929/exclude-certain-child-from-retrieving-firebase/69456805?noredirect=1#comment122766442_69456805) – JuFa512 Oct 13 '21 at 09:06
  • Where does that leave this question? Does it mean your link was actually a duplicate? – Frank van Puffelen Oct 13 '21 at 14:20

1 Answers1

1

Firebase security rules don't filter the data. They merely enforce that the data you're trying to access is allowed by the rules.

This is so important that there's even a documentation section about it: rules are not filters. It's also a common source of confusion though, given these previous questions on the topic.

Since in your rules nobody is granted access at /users, the code that tries to read from /users is rejected. And since your test user apparently was blocked by user1, the rule there rejects their access.


To securely query data the rules and code need to work together. The code should only request data it is allowed to access, so that the rules can then verify that.

In your case that'd mean that a user can only request /users if they somehow exclude users that have blocked them. This unfortunately isn't possible in Firebase queries, so you'll have to come up with a different data model for this use-case, or by loading the user data one-by-one. The latter is not nearly as slow as you may initially think, as Firebase pipelines the requests over a single connection.

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