Reputation: 1098
Say I have a user collection like so:
users{
userId1234 : {
name: "Joe",
interests: "Programming",
score: 1337
}
}
Is it possible to write rules that would allow
let user = {name:"Joey",interests:"Code"};
db.ref("users/").child("userId1234").update(user);
But not allow:
let user = {name:"Joey",interests:"Code",score:9000};
db.ref("users/").child("userId1234").update(user);
Essentially, I want to protect a certain field from being written (score in this example). I know I have the option of moving the field out to another collection, but I'd prefer to be able to do this if possible.
Here are the methods I've tried so far that have not worked:
"users":{
".write":"auth!=null",
"$userId":{
"score":{".write":false},
"$otherFields":{".write":"auth != null"}
}
}
^This blocks writes to /users/userId/score, but it doesn't block /users/userId with an object containing a score attribute.
"users":{
".write":"false",
"$userId":{
"score":{".write":false},
"$otherFields":{".write":"auth != null"}
}
}
^This allows me to write to the fields correctly, but completely blocks .update().
Thanks! -Joe
Upvotes: 3
Views: 1402
Reputation: 1098
My Solution
"users":{
"$userId":{
".write":"auth!=null",
".validate":"newData.child('score').val()
===data.child('score').val()",
"score":{".write":false},
"$otherFields":{".write":"auth != null"}
}
}
".validate": "!newData.hasChildren(['score'])" doesn't work because "newData" is actually the future merge result of the update data, not the raw data being posted, and if you have a score there already, it will fail.
Upvotes: 2