1

I'm trying to develop a simple Chat app using Firebase platform. To show a list of conversations I'm using FirebaseRecyclerAdapter. The thing is, that I can't figure out how to properly set the rules so users can only access conversations, that they are members of.

This is what my Firebase DB structure looks like.

{
    "conversations": {
        "cid1": {
            "title": "Conversation1"
        },
        "cid2": {...
        },
        "cid3": {...
        }
    },
    "members": {
        "cid1": {
            "uid1": true,
            "uid2": true
        },
        "cid2": {...
        },
        "cid3": {...
        }
    },
    "users": {
        "uid1": {
            "name": "User1"
        },
        "uid2": {...
        },
    }
}

And these are the rules I'm trying to apply.

  {
    "rules": {
        "conversations": {
            "$conversation_id": {
                ".read": "root.child('members').child($conversation_id).child(auth.uid).exists()",
            }
         },
     }
  }

By applying this rules and using FirebaseRecyclerAdapter I'm getting this error.

Listen at /conversations failed: DatabaseError: Permission denied

I suppose it's because I'm allowing users to read to conversation element, but not the whole list of conversations. Anybody has an idea how to solve this problem?

  • what is `mid1`, `mid2`? – adolfosrs Jun 25 '16 at 12:04
  • We need to see the code you are using to access it. – adolfosrs Jun 25 '16 at 12:06
  • @adolfosrs: It's supposed to be the user id. Edited the structure, so I hope it makes more sense now. – Marek Abaffy Jun 25 '16 at 12:15
  • There is not much code to show. I just basically reference the node mRef = FirebaseDatabase.getInstance().getReference().child("conversations/"); and then create the adapter new FirebaseRecyclerAdapter( Conversation.class, android.R.layout.two_line_list_item, ConversationItemHolder.class, mRef) {...} – Marek Abaffy Jun 25 '16 at 12:19
  • I would start by removing the slash inside `.child("conversations/")`. let it be just `.child("conversations")`. – adolfosrs Jun 25 '16 at 12:27

1 Answers1

0

You're falling for one of the pitfalls in Firebase's security rules: you cannot use security rules to filter data.

Your list adapter is listening to /conversations. That read operation will succeed or fail in its entirety, based on whether the user has read permission on /conversations.

Since you don't grant read permission on /conversations the listener will be cancelled. This is known as Rules Are Not Filters in the documentation and has been covered frequently here on Stack Overflow (because it's such a common pitfall). For one of the oldest and still best answer, see: Restricting child/field access with security rules

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