我有一个功能(并且我已经在没有功能的情况下对其进行了测试,只是为了检查引用或某些内容是否存在问题):
function resourceIsValidSomething() {
return request.resource.data.something is string ...;
}
然后:
allow create: if request.auth != null && resourceIsValidSomething();
和
allow update: if request.auth != null && resourceIsValidSomething();
但是在测试更新规则时,我会收到此错误消息:
错误:simulator.rules行[19]的列[17]。在对象上未定义属性资源。
根据documentation,我的规则应该正确。
我在做什么错了?
真实示例:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function isGod() {
return get(/databases/$(database)/documents/employees/$(request.auth.uid)).data.role == 'god';
}
function allowedUser() {
return request.resource.data.assignedTo.uid == request.auth.uid || isGod();
}
match /stores/{storeId} {
allow read: if request.auth != null;
match /imeis/{imeiId} {
function resourceIsValidImei() {
return request.resource.data.imei is string &&
request.resource.data.imei.size() > 0 &&
request.resource.data.type is string &&
request.resource.data.type.size() > 0 &&
request.resource.data.dateAdded is timestamp &&
request.resource.data.createdBy.uid == request.auth.uid;
}
allow read: if request.auth != null;
allow create: if request.auth != null &&
isGod() && resourceIsValidImei();
allow update: if request.auth != null && allowedUser();
}
答案 0 :(得分:2)
“未在对象上定义属性资源”
您不能在 Firebase 规则表达式中使用不存在的属性。
例如,以下将引发类似的错误。
read: if request.foobar == 'some value';
那是因为 foobar
不存在,并且规则会提出它是 undefined
。与右侧的 'some value'
的比较永远不会发生,并且不会评估其余的规则表达式。
像 request
这样的对象实现了 Map()
接口。
https://firebase.google.com/docs/reference/rules/rules.Map
因此您可以使用 Map.get()
方法重写规则,该方法不会引发错误并为缺失的条目提供默认值。
read: if request.get('foobar', null) == 'some value';
所以现在我们在规则中安全地引用 foobar
。
我有一个函数(我在没有函数的情况下测试了它,只是为了检查参考或其他东西是否有问题):
并非规则中的所有请求都会产生 resource
。如果文档不存在,则永远不会设置 resource
上的 request
属性。因此,尝试读取它会产生上述错误。您可以通过检查 null
来解决此问题。
function resourceIsValidSomething() {
return request.get('resource', null) != null && request.resource.data.something;
}
您可能仍会收到类似 false for "get" & L10
那是因为 request.get('resource', null) != null
检查将使规则失败。您可以决定允许访问不存在的文档,以便完成查询。
规则看起来像这样。
function resourceIsValidSomething() {
return request.get('resource', null) == null || request.resource.data.something;
}
因此允许访问缺少的资源或仅访问带有 data.something
的资源。
由您决定哪种方法最适合您的用例。
答案 1 :(得分:-1)
尝试从request.
的任何实例中删除request.resource
。即更改:
return request.resource.data.assignedTo.uid == request.auth.uid || isGod();
到
return resource.data.assignedTo.uid == request.auth.uid || isGod();
Google似乎在某些领域更新了文档,但在其他方面没有更新,但是resource
不再存储为request
的属性