依赖于文档参考的Firestore访问规则

时间:2018-10-10 19:53:04

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

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

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

const retrievedDoc = await getFirestoreDocument();
console.log(retrievedDoc.docRef.id); // "jRmSeMYDMKiOPGsmkdaZ"

我正在尝试在Firestore规则中完成同样的事情。有一个名为isOwner的{​​{3}}。它在文档路径上使用Firestore规则custom function进行调用,然后尝试访问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(我需要的ID)无论如何都不会在get调用中提供。

2 个答案:

答案 0 :(得分:0)

基于文档:

get()方法应该返回一个Resource对象,该对象应该包含一个.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;
    }
  }

}

但是,尝试时总是出现错误property id is undefined on object.data可以访问,因此我认为api中存在问题。

答案 1 :(得分:0)

更新

实际上,引用是here中所述的Firestore规则中的Path对象。因此,您可以通过所需路径部分的索引来访问ID。

在此示例中,我使用传入文档的数据(该数据具有参考对象)从get()

查找另一个文档上的属性。
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[4]].canBeRelated

     // the [4] assumes the path to be `databases/$(database)/documents/contacts/contactId`
     // your exact index would vary for your data structure
   }
}

第一个答案

这仅在Firestore仪表板规则模拟器中有效,而不是本地仿真或生产Firestore的有效示例。

今年已经一岁了,但是我遇到了同样令人费解的问题,但不是来自get()的数据,而是来自request.resource.data的数据。我不确定规则中应提供哪些内容(甚至没有__name__可用),但是如果您要访问数据上的资源引用,则ID大小是可预测的(例如20个字符),您只需获取要检查的资源上path的范围

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,因为路径在那里。 It appears Firestore won't support this出于任何原因。