To illustrate my use case, consider a two-way relationship between users and groups. Users can belong to a group, and groups comprise a list of users.
{
"users": {
"alovelace": {
"name": "Ada Lovelace",
"groupId": "techpioneers",
},
"eclarke": {
"name": "Edmund M. Clarke"
},
// ...
},
"groups": {
"techpioneers": {
"name": "Historical Tech Pioneers",
"members": {
"alovelace": true,
"ghopper": true
}
},
// ...
}
}
To associate eclarke
to a group, the client should update both paths (/users/eclarke/groupId
and /groups/techpioneers/members/eclarke
) in a single update so that there's no intermidiate invalid state.
To ensure this, I set the security rules for each path to reference each other:
{
"rules": {
"users": {
"$userId": {
"groupId": {
".validate": "newData.parent().parent().parent().child('groups').child(newData.val()).child('members').hasChild($userId)"
}
}
},
"groups": {
"$groupId": {
"members": {
"$memberId": {
".validate": "newData.parent().parent().parent().child('users').child($memberId).child('groupId').val() === $groupId"
}
}
}
}
}
}
I cannot use root
here becaue I would be looking at old database state.
Is there a better way to do this? (without having to make multiple .parent()
calls)
CodePudding user response:
Unfortunately there is no newRoot
variable, which would solve the multiple parent
calls. That concept was added in the Bolt security rules language, but since it was never added to the regular JSON language, Bolt also compiles it down to the required number of parent
calls.
So for the moment, what you have it the correct way to do this. It would not be a bad idea to file a feature request, as it may have been a while since the team saw this request.