【问题标题】:What is the proper way to handle "Permission Denied" when a Firestore document does not exist当 Firestore 文档不存在时,处理“权限被拒绝”的正确方法是什么
【发布时间】:2021-04-12 13:30:58
【问题描述】:

我已经为 Firestore 编写了规则,但是,当文档不存在时,它会引发“缺少或权限不足错误”。例如

firebase.firestore().collection('shipments').doc(order_doc_id)
.onSnapshot(fsResponse => {
...
)}

当order_doc_id 不存在时抛出“Missing or Insufficient Permissions 错误”。

这是我的“货件”集合的安全规则:

allow read: if request.auth != null && (resource.data.book_data.seller_id == request.auth.uid || resource.data.buyer_id == request.auth.uid)

理想情况下我希望它能够使用fsResponse.exists === false 成功解决,然后向用户显示“未找到”屏幕,但事实并非如此,并且错误没有说明存在文件。

处理这种情况的正确方法是什么?

【问题讨论】:

  • 即使文档不存在,您通常也不会收到“缺少或权限不足错误”。您确定其他设置没有任何副作用吗? (安全规则,...)
  • 这是我的“货件”集合安全规则allow read: if request.auth != null && (resource.data.book_data.seller_id == request.auth.uid || resource.data.buyer_id == request.auth.uid)
  • @RenaudTarnec 所以从技术上讲,如果文档不存在,resource.data.book_data.seller_id == request.auth.uid 不可能是真的,但我仍然想知道它是否不存在而不是获得权限被拒绝错误

标签: firebase google-cloud-firestore


【解决方案1】:

此答案基于@RenaudTarnec 的answer。

当前规则失败的原因是它们在用于不存在的文档时会引发错误。任何引发错误的规则都被视为该规则阻止了访问。

您当前的阅读规则:

allow read: if request.auth != null
            && (resource.data.book_data.seller_id == request.auth.uid
               || resource.data.buyer_id == request.auth.uid);

对于存在的文档,如果访问用户是卖方或买方,则规则允许读取访问权限。但是当文档不存在时,resource 将是 null - 这会导致语法错误,您尝试读取 data 对象上的属性 data - 阻止读取。在 Firebase 控制台的 Rules Playground 中测试您的规则时,您可以看到这种行为。

要允许读取不存在的文档,您需要添加null-检查resource。为防止滥用,您可能仍希望要求用户登录。

allow read: if request.auth != null
            && (resource == null
               || resource.data.book_data.seller_id == request.auth.uid
               || resource.data.buyer_id == request.auth.uid);

【讨论】:

    【解决方案2】:

    根据你的cmets,你的问题如下:

    shipments 集合的安全规则是

    allow read: if request.auth != null && (resource.data.book_data.seller_id == request.auth.uid || resource.data.buyer_id == request.auth.uid)
    

    因此resource.data.book_data.seller_id == request.auth.uid 如果文档不存在则不能为真

    因此,当我在不存在的文档上设置侦听器时,该规则会引发“缺少或权限不足错误”。

    但是,

    我仍然想知道它是否不存在而不是得到 权限被拒绝错误


    以下安全规则,使用!exists 来检查文档是否不存在,应该可以解决问题:

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /shipments/{shipmentId} {
          allow read: if (
            (!exists(/databases/$(database)/documents/shipments/shipmentId))
            || (request.auth != null && (resource.data.book_data.seller_id == request.auth.uid || resource.data.buyer_id == request.auth.uid))
            );
        }
      }
    }
    

    【讨论】:

    • 不是!exists(currentPath) 导致数据库读取,你不能只使用resource == null吗?
    • 这行得通!我按照@samthecodingman 的建议将其调整为使用resource == null。非常感谢你们俩。
    • 更好的方法@samthecodingman,你应该添加一个答案,它应该是被接受的。
    猜你喜欢
    • 1970-01-01
    • 2019-03-20
    • 2021-11-16
    • 1970-01-01
    • 2019-10-01
    • 1970-01-01
    • 2020-09-12
    • 2019-06-13
    • 2019-02-24
    相关资源
    最近更新 更多