Firebase Database Rules to match row

Viewed 936

I am using a Firebase Realtime Database. I have the following data:

enter image description here

I also have the rules:

{
  "rules": {
      ".read": "auth != null",
      ".write": "auth != null",
      "chat": {
        "$key": {
            ".read": "data.child('memberId1').val() === auth.uid && data.child('memberId2').val() === auth.uid",         
            ".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"          
        }
      },

The initial rule works perfectly:

      ".read": "auth != null",
      ".write": "auth != null",

Problem

The following 2 rules have no effect.

      "chat": {
        "$key": {
            ".read": "data.child('memberId1').val() === auth.uid && data.child('memberId2').val() === auth.uid",         
            ".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"          
        }
      },

As you can see, in order to test these rules, in the first rule, I have made an impossible condition of memberId1 and memberId2 both equal to the users uid. As a result I would expect it to fail.

If I remove:

      ".read": "auth != null",
      ".write": "auth != null",

and just have:

      "chat": {
        "$key": {
            ".read": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid",         
            ".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"          
        }
      },

Then access is denied. Even if I change it to:

 "data.child('memberId1').val() === 'h6qQg5YfQveTaCyBEXwDMSJPqwk1' 

The following is also denied:

  "chat": {
    "Ko7w9XTtuRVN4p6CMp7": {
        ".read": true,   

Question

How should I structure the rules to allow that a user may only access a row where their uid matches either memberId1 or memberId2?

Thanks

UPDATE

I have the following code:

   findChats(): Observable<any[]> {
        return this.af.database.list('/chat/', {
            query: {
                orderByChild: 'negativtimestamp'
            }
        }).map(items => {
            const filtered = items.filter(
                item => (item.memberId1 === this.me.uid || item.memberId2 === this.me.uid)
            );
            return filtered;
        });
    }

My question is similar to this one. I try the following with no success:

{
  "rules": {
      "chat": {
        "$id": {
            ".read": true
        }
      },
1 Answers
Related