我正在尝试为Firebase guide中的“将数据另存为事务”博客应用示例创建安全规则。
用户可以增加或减少帖子的星号,同时在节点中包含或删除自己的UID。
我写了以下规则: (我删除了计数器增加/减少的规则,因为它们超出了问题的范围)
“stars”: {
".read": true,
"$postId”: {
".write": "auth != null && (newData.child('users').child(auth.uid).exists() || data.child('users').child(auth.uid).exists())",
"users": {
"$userId": {
".validate": "$userId === auth.uid"
}
}
}
}
星星节点的例子:
“stars”: {
“postId1”: {
starCount: 2,
"users": {
“userId1”: true,
“userId2”: true
}
}
}
规则适用于将用户添加到“用户”节点,但删除时会出现问题。
一个卑鄙的用户可以从“用户”节点中删除任何其他用户,只需用空节点更新它。或者包含之前所有用户的节点,减去他选择删除的用户。 “.validate”规则(" $ userId === auth.uid")对于被提交的空节点不起作用,我无法编写一个规则来检查是否所有用户都是在更新之前的数据库中仍然存在。
如果我没有使用事务,我解决问题的方法是将“.write”规则移到“$ userId”下,限制一次只有一个用户的uptate,并且只有相同的UID作为已登录用户。
类似的东西:
“stars”: {
".read": true,
"$postId”: {
"users": {
"$userId": {
".write": "auth != null && $userId === auth.uid"
}
}
}
"starCount": {
".write": true
}
但是由于我正在使用事务进行数据库更新,我需要" $ postId下的“.write”规则,允许同时更新“users”节点和“starCount”节点时间。在我的上一个例子中不可能的东西(" $ postId下没有“.write”规则)。
所以它看起来像一个Catch-22。或者我使用事务但是我无法使用规则保护starCount,或者我将其作为正常的多次更新来保护,但是增加了计数器的并发性好处。
如何正确保护“将数据保存为交易”博客应用程序示例?