Firebase Firestore安全规则-{wildcard}在获取集合时既不是null也不是null

Firebase Firestore安全规则-{wildcard}在获取集合时既不是null也不是null,firebase,google-cloud-firestore,firebase-security,Firebase,Google Cloud Firestore,Firebase Security,我已在firestore上设置了读取规则,当按id获取单个文档时,该规则可以正常工作,但由于FirebaseError:缺少或权限不足而失败。获取集合时出错 似乎是路径中的通配符在查询集合时未正确绑定。我已经归结为一个最小的例子,从逻辑上讲,我认为不应该不通过许可,但它确实通过了。 详情如下: 数据(已格式化,但当然已在集合/域中组织): 规则: service cloud.firestore { match /databases/{database}/documents {

我已在firestore上设置了读取规则,当按id获取单个文档时,该规则可以正常工作,但由于
FirebaseError:缺少或权限不足而失败。
获取集合时出错

似乎是路径中的通配符在查询集合时未正确绑定。我已经归结为一个最小的例子,从逻辑上讲,我认为不应该不通过许可,但它确实通过了。 详情如下:

数据(已格式化,但当然已在集合/域中组织):

规则:

service cloud.firestore {
    match /databases/{database}/documents {
        match /items/{itemId} {
            allow read: if itemId != null;
        }
    }
}
我用来访问数据库的代码(typescript)

// This line works fine, returns the document
firebase.firestore().collection("/items").doc("item1").get()

// This line gets a "FirebaseError: Missing or insufficient permissions." error
firebase.firestore().collection("/items").get()
我试着把规则改成

allow read: if itemId != null || itemId == null;
这在逻辑上应该永远是正确的。但是,结果仍然是一样的,这使我相信绑定到
itemId
通配符时存在一些问题

作为一种精神检查,我还将规则更改为

allow read: if true;
现在,集合和文档上的
get()
都可以正常工作(如预期),没有任何权限错误


那么我是在这里遗漏了什么,还是这是firestore中的一个bug?

首先,你的规则对我来说没有意义。检查文档id是否不为空的目的是什么?有效文档不可能具有
null
文档id


发件人:

在编写查询以检索文档时,请记住安全性 规则不是过滤器,查询是全部或无。为了节省你的时间和精力 资源,云Firestore根据查询的潜力评估查询 结果集,而不是所有字段的实际字段值 文件。如果查询可能返回 客户端没有读取权限,整个请求失败

在您的情况下,firestore可能认为您的查询可能会返回您可能没有阅读权限的文档。它不知何故认为,某些文档可能具有
null
文档id,从而拒绝整个请求


当您将规则更改为
允许读取:如果为true之所以有效,是因为Firestore对其进行了评估,并且知道该规则肯定会为每个文档传递,因此授予您读取权限。

您建议的规则不起作用,因为(按照当前的实施方式),通配符变量对于列表(查询)类型的请求具有未定义的值(但不适用于get类型请求,因为文档ID当然直接来自客户端)。查询可能匹配多个文档,并且您的查询没有指定文档ID,因此无法在规则中使用

如果您希望规则根据每个文档来决定它是否属于查询结果,那么这也永远不会起作用。这是因为规则不是筛选器。所有筛选器都必须来自客户端。如果规则会拒绝给定筛选器可能存在的任何文档,则entire请求被拒绝。(在请求时实际检查所有文档是不可扩展的,这可能非常慢)


换句话说,如果要影响查询,请不要使用通配符变量。只使用可以匹配的文档的属性,并确保客户端指定了所有相关筛选器。

您希望此规则何时明确拒绝访问?在我看来,您没有明确的拒绝案例,这意味着您的规则一开始并没有多大用途。当然,我的领域比这更复杂,我只是将问题归结为一组最小的代码来重现问题。主要问题是绑定通配符/文档id的问题禁止我制定任何有意义的访问规则。我在文档中看不到任何内容强调通配符只适用于获取单个文档,而不适用于集合查询。我认为它会更好(就本问题而言)用一个实际的规则来展示你在这里试图实现的目标,而这个规则并没有按照你期望的方式工作。如果你的规则没有明确的目的,很难说你是否正确地思考了这个问题。好的一点,应该这样做。我只是想简单一点,因为我认为我已经缩小了问题的范围s、 我不想把问题弄得一团糟,可以安全地说,“{wildcard}只能通过将单个文档id传递到
get()
”的查询在规则中使用吗?例如:
db.collection(“cities”).doc(“SF”).get();
可以工作,而
db.collection(“cities”).where(“大写”,“=”,true)。get()
不能吗?
allow read: if true;