【问题标题】:Firestore security rules: get() use in hasAny() list methodFirestore 安全规则:在 hasAny() 列表方法中使用 get()
【发布时间】:2020-07-08 12:24:28
【问题描述】:

我想知道这个安全规则是否可行:

function productForUser() {
        return resource.data.products.hasAny(get(/databases/$(database)/documents/Users/$(request.auth.uid)).data.products);
    }

当我尝试在 Firebase 网站上的测试平台上对其进行测试时,它是成功的。但是,当我尝试使用 Javascript 运行它时,使用此查询时,读取被拒绝,“权限缺失或不足”:

query.where("products", "array-contains", productId);

我可以确认用户拥有产品数组,其中包含正在查询中查找的特定产品。

提前致谢。

【问题讨论】:

    标签: firebase google-cloud-firestore firebase-authentication firebase-security


    【解决方案1】:

    您的规则在控制台模拟器中有效,因为模拟器仅支持对单个文档的“获取”类型请求。它不适用于查询,因为security rules are not filters。该规则不会针对集合中的每个文档进行评估,因为对于非常大的集合来说,这根本无法很好地扩展。要指定查询条件,您需要提供准确的值以从客户端检查 - 您将无法使用 get() 来查找其他值。

    如果您想在发布规则之前测试查询,则不应使用模拟器,而应使用local emulator 来测试实际执行查询的代码。

    【讨论】:

    • 感谢您的评论。对于为我正在做的事情编写安全规则有什么建议吗?我宁愿坚持解决这个问题,保留 where 子句会很好,而且我不能提供两个“array-contains”子句,因为它不受支持。还有什么我可以做的吗?
    • 使规则适用于查询的唯一方法是确定权限所需的所有数据都包含在查询本身中。这意味着您可能必须重组数据并将一些数据复制到“产品”文档中。
    • 再次感谢您的回复。我试过这样做,我想验证的其他数据实际上也在文档中的一个数组中(即 userId),但我不能使用它,因为我不能用两个array-contains 查询。我尝试将array-containsin 查询结合使用,因为它只是数组中我需要比较的一个字符串元素。这也给了我同样的错误,即使在添加了安全规则以检查 userId 是否在数组中之后也是如此。有没有其他方法可以重新构建查询以使其正常工作?再次感谢您的帮助。
    • 我不知道,没有看到您的实际数据和查询。请发布另一个问题,其中包含任何人都可以使用的具体细节来重现该问题。
    猜你喜欢
    • 1970-01-01
    • 2020-08-22
    • 2018-03-19
    • 2021-05-12
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    • 2022-12-11
    相关资源
    最近更新 更多