Tom3652
Tom3652

Reputation: 2957

Read rule is not validated Firebase RTDB

I am trying to make my read rules working in RTDB as follow :

{
  "rules": {
    "test": {
      "$uid": {
        ".read": "data.exists()",
      }
    },
  }
}

Here is the data in test node :

{
  "test" : {
    "anyuid" : {
      "content" : {
        "uid1" : "gnjdssd",
        "uid2" : "fnvdjkcx"
      },
      "at" : "2491795"
    }
  }
}

Here is my code that is denied (actually tested with and without orderByChild but in my real query i need the orderByChild so if this changes anything in the rule except the .indexOn i prefer to specify it) :

FirebaseDatabase.instance.ref().child("test").orderByChild("at").get()

The log : I/RepoOperation(29129): get for query /test falling back to disk cache after error: Permission denied

My goal is to allow read if there is a real condition such as :

data.child('content/'+auth.uid).exists()

But the data.exists() is is not reached in this case.

What i am missing here and how can i implement the rule i want please ?

EDIT :

my data structure is :

{
  "chats": {
    "$chatID": {
      members: {
        "userID1": true,
        "userID2": true,
      }
    }
  }
}

I want to allow userID1 to read only chats where his id is actually in the member map of the chat.

Upvotes: 2

Views: 56

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598765

Your code tries to read from /test, but if we look at the security rules you shared, nobody has permission to read from that node. Keep in mind that rules are not filters, but instead merely ensure that each operation does no more than what is allowed.

If you want to stuck to your current rules, you'll need to know the key of the test node you want to read:

FirebaseDatabase.instance.ref().child("test").child("uidOfUser").get()

If you want to allow the query in your code, you'll need to allow reading from /test:

{
  "rules": {
    "test": {
      ".read": "data.exists()",
    },
  }
}

Note though that this ".read": "data.exists()" is a noop, as there's no security risk in allowing someone to read data that doesn't exist.


Update based on your edit showing the chats structure. If you want to allow the user to read a chat if they are a member, you can do that with:

{
  "rules": {
    "chats": {
      "$chatid": {
        ".read": "data.child('members').child(auth.uid).exists()"
      }
    },
  }
}

There is no way to securely allow reading from /chats in this case though. To allow a user to find their own chats and read them securely, you'll need to add another, inverted data structure mapping the UIDs to their chat IDs. For more on this, see:

Upvotes: 3

Related Questions