Google cloud firestore Firebase安全规则,确保一个“;数组删除";仅限,且仅限用户ID
我有通知记录,其中有文本和用户列表(最多10个) 当用户阅读/确认通知时,我想将其从可以看到通知的用户列表中删除(这样他就不会再收到任何通知) 为此,当用户按下“隐藏通知按钮”时,他发送一个更新通知记录的请求,其中包括:Google cloud firestore Firebase安全规则,确保一个“;数组删除";仅限,且仅限用户ID,google-cloud-firestore,firebase-security,Google Cloud Firestore,Firebase Security,我有通知记录,其中有文本和用户列表(最多10个) 当用户阅读/确认通知时,我想将其从可以看到通知的用户列表中删除(这样他就不会再收到任何通知) 为此,当用户按下“隐藏通知按钮”时,他发送一个更新通知记录的请求,其中包括: users: FieldValue.arrayRemove(uid) 我希望使用安全规则强制用户: 不会更改通知记录的其他部分 在arrayRemove部分发送其uid,并且仅发送其uid 试用 allow update: if request.auth.uid
users: FieldValue.arrayRemove(uid)
我希望使用安全规则强制用户:
- 不会更改通知记录的其他部分李>
- 在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李>
非常感谢任何提示、帮助和想法。如果没有循环,我认为这是不可能的,因为安全规则中不存在循环。好吧:如果你知道所有的用户,你也许能够列举所有的选项,基本上展开不可能的循环。但即使这在安全规则中是可能的,规则也会非常冗长
我建议创建一个子集合,其中每个UID存储在单独的文档中。在该子集合中,您可以通过只允许用户删除自己的文档来实现您的需求。我认为如果没有循环,这是不可能的,因为安全规则中不存在循环。好吧:如果你知道所有的用户,你也许能够列举所有的选项,基本上展开不可能的循环。但即使这在安全规则中是可能的,规则也会非常冗长
我建议创建一个子集合,其中每个UID存储在单独的文档中。在该子集合中,您可以通过只允许用户删除自己的文档来实现您的需求。我也遇到过类似的情况,这是一个相当棘手的问题。 这就是我的诀窍:
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
removeAll()
从旧数组中减去新数组(现在减少了1uid
),并返回一个带差值的数组。在本例中,它返回一个数组,该数组只包含您选择的arrayRemove()
的单个uid
。然后我们只需检查uid
——它只能存在于位置[0]
——并确保它等于经过身份验证的用户的uid
我有一个类似的情况,这是一个相当脑筋急转弯。 这就是我的诀窍:
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
removeAll()
从旧数组中减去新数组(现在减少了1uid
),并返回一个带差值的数组。在本例中,它返回一个数组,该数组只包含您选择的arrayRemove()
的单个uid
。然后我们只需检查uid
——它只能存在于位置[0]
——并确保它等于经过身份验证的用户的uid
好的,谢谢你的回答。我想Firestore将在某个时候发展并提供解决方案。好的,谢谢你的回答。我想Firestore会在某个时候发展并提供解决方案。你的第三条规则不应该是
请求.资源.数据.用户.大小()==1
,因为请求中应该只有一项吗?啊!看起来像是FieldValue.arrayUnion/FieldValue.arrayRemove
在验证发生之前对请求.resource.data
执行了一些魔术。看起来它具有所有以前的值。你的#3现在完全有道理了。谢谢第二行应该是request.resource.data.diff(resource.data.affectedKeys().hasOnly(['users'))你的第三条规则不应该是request.resource.data.users.size()==1
,因为请求中应该只有一项吗?啊!看起来像是FieldValue.arrayUnion/FieldValue.arrayRemove
在验证发生之前对请求.resource.data
执行了一些魔术。看起来它具有所有以前的值。你的#3现在完全有道理了。谢谢第二行应该是request.resource.data.diff(resource.data.affectedKeys().hasOnly(['users'))