Firebase 安全规则,确保一个“阵列移除"只有,并且只有 userId [英] Firebase security rules, ensure one "array remove" only, and only to userId
问题描述
我有通知记录,其中包含文本和用户列表(最多 10 个).
I have notification records where there is a text and a list of users (max 10).
{text: "Beware of the dog", users: [ uid1, uid2, uid3, ... ]}
当用户阅读/确认通知时,我想将他从可以看到通知的用户列表中删除(然后他将不再收到任何通知).
When a user read/acknowledge the notification, I want to remove him from the list of users who can see the notification (then he won't get any anymore).
为此,当用户按下隐藏通知按钮"时,他会发送一个更新通知记录的请求:
For that, when the user press the "hide notification button", he send a request to update the notification record with:
users: FieldValue.arrayRemove(uid)
我想使用用户的安全规则:
I want to enfore with security rules that the user:
- 不会更改通知记录的其他部分.
- 在arrayRemove 部分发送它的uid 和仅它的uid.
尝试过
allow update: if
request.auth.uid != null
&& request.auth.uid in resource.data.users
&& request.resource.size() == 1
&& request.resource.data.users != null;
- request.resource.size == 1 不起作用.不知道为什么,因为我的请求中只有一个字段.
- 我无法确保 arrayRemove 严格限于其 uid.
非常感谢任何提示、帮助和想法.
Any hint, help, idea well appreciated.
推荐答案
我遇到了类似的情况,这是一个脑筋急转弯.这就是对我有用的技巧:
I had a similar situation and it was quite a brain teaser. This is what did the trick for me:
allow update: if
request.auth.uid != null
&& request.resource.data.diff(resource.data).affectedKeys().hasOnly([data])
&& request.resource.data.users.size() == resource.data.users.size() - 1
&& resource.data.users.removeAll(request.resource.data.users)[0] == request.auth.uid
特别是:
- 第一条规则是您拥有的规则 - 检查用户身份验证
- 第二条规则检查新旧文档之间的差异,并确保唯一受影响的键是名为
data
的键 - 第三条规则确保新数组恰好比旧数组短 1 个项目(这样一次只能删除 1 个项目)
- 第四条规则用
removeAll()
从旧数组中减去新数组(现在减少1个uid
)并返回一个数组与他们的区别.在这种情况下,它返回一个数组,其中只包含您选择arrayRemove()
的单个uid
.然后我们简单地检查uid
- 它只能存在于位置[0]
- 并确保它等于经过验证的uid
用户.
- The first rule is the one you had - checks for user authentication
- The second rule checks the difference between the new and the old document and makes sure that the only key affected is the one named
data
- The third rule makes sure that the new array is exactly 1 item shorter than the old one (so that only 1 item can be removed at a time)
- The fourth rule subtracts the new array (now reduced by 1
uid
) from the old one withremoveAll()
and returns an array with their difference. In this case, it returns an array which contains only the singleuid
that you chose toarrayRemove()
. Then we simply check thatuid
- which can only exist at position[0]
- and make sure it is equal to theuid
of the authenticated user.
这篇关于Firebase 安全规则,确保一个“阵列移除"只有,并且只有 userId的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!