【问题标题】:Firebase security rules, ensure one "array remove" only, and only to userIdFirebase 安全规则,确保只有一个“数组删除”,并且只对 userId
【发布时间】:2020-08-22 18:50:02
【问题描述】:

我有通知记录,其中包含文本和用户列表(最多 10 个)。

{text: "Beware of the dog", users: [ uid1, uid2, uid3, ... ]}

当用户阅读/确认通知时,我想将他从可以看到通知的用户列表中删除(然后他将不再收到任何通知)。

为此,当用户按下“隐藏通知按钮”时,他会发送更新通知记录的请求:

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。

任何提示、帮助、想法都非常感谢。

【问题讨论】:

    标签: google-cloud-firestore firebase-security


    【解决方案1】:

    我也遇到过类似的情况,这真是一个脑筋急转弯。 这就是我的诀窍:

    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
    

    具体来说:

    1. 第一条规则是您拥有的 - 检查用户身份验证
    2. 第二条规则检查新旧文档之间的差异,并确保唯一受影响的键是名为 data 的键
    3. 第三条规则确保新数组比旧数组短 1 项(因此一次只能删除 1 项)
    4. 第四条规则减去新数组(现在减少了 1 个uid)与 removeAll() 的旧数组并返回一个数组及其差异。在这种情况下,它返回一个数组,其中仅包含您选择的 arrayRemove() 的单个 uid。然后我们简单地检查 uid - 它只能存在于位置 [0] - 并确保它等于经过身份验证的用户的 uid。

    【讨论】:

    • 您的第三条规则不应该只是request.resource.data.users.size() == 1,因为请求中应该只有一项吗?
    • 啊!看起来FieldValue.arrayUnion/FieldValue.arrayRemove 在验证发生之前对request.resource.data 做了一些魔术。看起来它具有所有以前的值。你的#3 现在完全有意义了。谢谢
    • 第二行应该是request.resource.data.diff(resource.data).affectedKeys().hasOnly(['users'])
    【解决方案2】:

    我认为如果没有循环,这是不可能的,安全规则中不存在循环。好吧:如果您了解所有用户,您可能能够枚举所有选项,从而展开不可能的循环。但即使这在安全规则中是可能的,规则也会非常冗长。

    我建议创建一个子集合,其中每个 UID 都存储在单独的文档中。在该子集合中,您可以通过只允许用户只删除他们自己的文档来实现您的要求。

    【讨论】:

    • 好的,谢谢你的回答。我猜 Firestore 将在某个时候发展并为此提供解决方案。
    猜你喜欢
    • 2019-07-12
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 2018-12-26
    相关资源
    最近更新 更多