Ad

Data Validation Issue Firebase RealTime Database Rules

I am trying to make some security rules to allow authenticated users to access (read / write) chats path based on some conditions for data validation.

Here are my rules :

{
  "rules": {
    "chats": {
      "$chatID": {
        ".read": "data.child('members/'+auth.uid).exists()",
        ".write": "(!data.exists() && newData.child('members').exists() && newData.child('members/'+auth.uid).exists()) || data.child('members/'+auth.uid).exists()",  
      }
    },
  }
}

And here is my json :

{
    "chats/1d771b40-917c-11ec-b57d-a55c6126c658":{
        "uid":"1d771b40-917c-11ec-b57d-a55c6126c658",
        "name":"",
        "updatedAt":1645272534466,
        "createdAt":1645272279796,
        "senderID":"user1",
        "members":{
            "user1":true,
            "user2":true
        },
        "created":true,
    }
}

I don't understand why it's denied for writes, can you explain me please which value has newData exactly ?

I have setup a very basic rule to test :

{
  "rules": {
    "chats": {
      "$chatID": {
        ".read": "data.child('members/'+auth.uid).exists()",
        ".write": "newData.child('members').exists()",  
      }
    }
  }
}

That is denied, and i have also tried :

{
  "rules": {
    "chats": {
      "$chatID": {
        ".read": "data.child('members/'+auth.uid).exists()",
        ".write": "newData.parent().child('members').exists()",  
      }
    }
  }
}

According to the documentation i thought that newData was containing the json data that will happened if the write is allowed for the given path, meaning in this case :

{
        "uid":"1d771b40-917c-11ec-b57d-a55c6126c658",
        "name":"",
        "updatedAt":1645272534466,
        "createdAt":1645272279796,
        "senderID":"user1",
        "members":{
            "user1":true,
            "user2":true
        },
        "created":true,
}

So why newData.child('members').exists() returns false if I understood correctly ?

I have also tested newData.hasChild('members') and newData.hasChildren(['members']) but all give the same result (False).

Thanks in advance

Ad

Answer

You should pass the exact JSON that should go in the specified path/locations in the update request's data.

So the location to update a chat would be: chats/{chatId} and data/payload as shown below:

{
  "uid": "1d771b40-917c-11ec-b57d-a55c6126c658",
  "name": "",
  "updatedAt": 1645272534466,
  "createdAt": 1645272279796,
  "senderID": "user1",
  "members": {
    "user1": true,
    "user2": true
  },
  "created": true
}
Ad
source: stackoverflow.com
Ad