4
votes

I seem to be having a hard time with firebase security rules. I've read the guides, but the simulator results aren't descriptive enough (Would be much easier if we could just hover over a node, and a button pops up where we can update the rules).

Here's what my structure looks like:

chats
  - randomChatId01
    - name: "awesome chat"
    - members:
        - userId01 : true
        - userId02 : true
  - randomChatId02
    - members:
        - userId02 : true
  - randomChatId03
    - members:
        - userId01 : true
        - userId02 : true
  - ...

I only want a user to be able to read the chat nodes in which the node's child node members contains the authenticated user's auth.uid.

So in this case if userId01 were logged in, she would only have read access to randomChatId01 and randomChatId03.

This is the rule I have:

{
    "rules": {

        "chats": {

          "$chat": {
            ".read": "data.child('members').val().contains(auth.uid)"
          }
        }
    }
}

However it's returning the following in the simulator:

Attempt to read /chats with auth={"provider":"anonymous","uid":"eF4ztDEXz7"}
    /
    /chats

No .read rule allowed the operation.
Read was denied.
1

1 Answers

6
votes

This is because Firebase Security Rules are evaluated at the location that you read from.

You're trying to read /chats. The user does not have read permission to /chats, so the operations fails straight away.

If you read /chats/randomChatId01 as userId01 it will succeed.

This is covered in the documentation section rules are not filters. Also see Michael Lehenbauer's answer here: Restricting child/field access with security rules