user3833732
user3833732

Reputation: 901

Firebase Realtime Database Security Rules: need newData's child that is dynamically created and wildcard $ doesnt work

I only want to be able to add that user(object) to my "Entry" node if the name field exist in the "AllowedEntry" node.

-AllowedEntry
            |--ABC
            |     |--name: "ABC"
            |     |--age: 20
            |--LMN
            |     |--name: "LMN"
            |     |--age: 55
            |--XYZ
                  |--name: "XYZ"
                  |--age: 88
            
            
-Entry
      |--ABC
             |--name:"ABC"
             |--age:20
             |--dept:"Code"
             |--isAdmin:false
   

Over here the ABC record at Entry is possible because the name field value of ABC(ie "ABC") exists under AllowedEntry

but the below must fail

-Entry
      |--PQR
           |--name:"PQR"
           |--age:52
           |--dept:"dsfg"
           |--isAdmin:true

because this PQR objects name("PQR") doesnt exist under the node of AllowedEntry

This is what I have tried from my end but been unsuccessful. the Reading permission has been set successfully... we dont need that

"Entry": {
  "$id": {
    ".write": "root.child('AllowedEntry/'+ newData.child('$id').child('name').val() ).exists()",
  }
}

The above doesnt work because a wildcard '$id' doesnt work with newData.child()

And if i do away with the '$id' we are not able to access the child node in the Json eg.

"Entry": {
  ".write": "root.child('AllowedEntry/'+ newData.child(**???**).child('name').val() ).exists()",
}

I wouldnt know what to enter in the ??? since the Json that comes flying into our DB looks like this

{
  "ABC": {
    "name": "ABC",
    "age": 20,
    "dept": "Code",
    "isAdmin": true 
  }
}

You see Json with only

  {
     "name": "ABC",
     "age": 20,
     "dept": "Code",
     "isAdmin": true 
  }

would work perfectly with ".write": "root.child('AllowedEntry/'+ newData.child('name').val() ).exists()"

but then there would be only one reord in the ENTRY node.

Adding an image to show you the outputs, the Json and the dataenter image description here

Upvotes: 0

Views: 82

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

This fragment in your first rules snippet is wrong:

newData.child('$id').child('name')

The '$id' in there is just a literal string, rather than the value of the $id capture variable. To use the latter:

newData.child($id).child('name')

Also, there is no need for string concatenation and this is more readable:

"root.child('AllowedEntry').child(newData.child($id).child('name').val()).exists()"

In your screenshot I noticed that you:

  1. Define the rules on the $id node,
  2. Then use newData.child('$id').child('name').val() in your condition.

newData refers to the new data on the node where it is used. So this code now looks for a node named $id under the $id node, which exist. You probably want newData.child('name').val().

Upvotes: 1

Related Questions