Firebase 依赖文档引用的Firestore访问规则

Firebase 依赖文档引用的Firestore访问规则,firebase,google-cloud-firestore,firebase-security,Firebase,Google Cloud Firestore,Firebase Security,Firestore有一个类型,它是指向另一个Firestore文档的“指针”。使用firebase JavaScript客户端,您可以直接在引用上访问属性(例如文档“id”) 例如,如果有一个具有docRef属性的文档是firestore DocumentReference: const retrievedDoc = await getFirestoreDocument(); console.log(retrievedDoc.docRef.id); // "jRmSeMYDMKiOPGsmkda

Firestore有一个类型,它是指向另一个Firestore文档的“指针”。使用firebase JavaScript客户端,您可以直接在引用上访问属性(例如文档“id”)

例如,如果有一个具有
docRef
属性的文档是firestore DocumentReference:

const retrievedDoc = await getFirestoreDocument();
console.log(retrievedDoc.docRef.id); // "jRmSeMYDMKiOPGsmkdaZ"
我正试图在firestore规则内完成同样的事情。有一个名为
isOwner
。它对文档路径使用firestore规则调用,然后尝试访问
docRef.id
,就像上面的JavaScript客户端一样

get(/databases/$(database)/documents/path/to/$(id)).data.docRef.id
将文档的id值与当前用户的id值进行比较。但当我使用模拟器和真实代码测试时,它失败了。我觉得这应该行得通,但不行

工作原理是将id值直接作为字符串存储和使用(例如,
get(/path/id).docId
),而不是DocumentReference

我应该能够访问firestore规则中DocumentReference的
id
值吗?
我做错了什么吗


我希望避免在所述规则内执行第二个文档
get
。这是该规则的每个触发器的第二次“读取”。而且我认为无论如何,
get
调用中都不会提供文档id(这是我所需要的)。

基于文档:

get()
方法应该返回一个资源对象,该对象应该包含
.id
属性(以及
.data

例如,要限制作为书籍文档作者的经过身份验证的用户的
write
访问权限(作者文档由用户uid标识),您可以执行以下操作:

service cloud.firestore {
  match /databases/{database}/documents {
    match /books/{document=**} {
            allow write: if get(resource.data.authorReference).id == request.auth.uid;
    }
  }

}
然而,在尝试时,我总是在对象上遇到属性id未定义的错误。
.data
是可访问的,因此我认为api中存在问题。

更新

实际上,引用是Firestore规则中的
路径
对象,如文档所示。因此,您可以通过所需路径部分的索引来访问id

在本例中,我使用具有引用对象的传入文档的数据从
get()

第一个答案

这仅适用于Firestore仪表板规则模拟器,它不是本地仿真或生产Firestore的工作示例。

这已经有一年了,但我遇到了同样令人困惑的问题,但不是关于
get()
的数据,而是关于
请求.resource.data
的数据。我不确定规则中应该有什么可用(甚至不可用),但如果您访问数据上的资源引用,并且您有一个可预测的id大小(例如,20个字符),您可以简单地获得资源上要检查的
路径的范围

match /databases{database}/documents {
   match /contacts/{contact} {

     allow create: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.relatedRules[request.resource.data.relation.path[9:29]].canBeRelated

     // the [9:29] assumes the path to be `/contacts/20characterLongIdStr`
     // your exact range would vary for your data structure
   }
}

感觉资源引用对象至少应该有id,因为路径在那里。无论出于何种原因。

不是
get(/databases/$(database)/documents/path/to/$(id)).docRef.id
完全相同的
$(id)
?@FrankvanPuffelen不,
docRef
属性是对Firestore中其他地方文档的文档引用。@FrankvanPuffelen目的是:“如果此处的文档引用指向您,则授予访问权限”在这种情况下,您缺少一个
.data
,这是访问文档字段所必需的。类似于
get(/databases/$(database)/documents/path/to/$(id)).data.docRef.id
。请参阅抱歉@FrankvanPuffelen,这是我问题中的一个错误(正在修复)。我在实际规则文件中确实有
.data
match /databases{database}/documents {
   match /contacts/{contact} {

     allow create: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.relatedRules[request.resource.data.relation.path[9:29]].canBeRelated

     // the [9:29] assumes the path to be `/contacts/20characterLongIdStr`
     // your exact range would vary for your data structure
   }
}