Firestore的编写规则似乎自定义变量无效。 有谁知道为什么或已经看到类似的行为? 使用下面的代码,虽然uid在admin数组中,但我拒绝了访问。
service cloud.firestore {
match /databases/{database}/documents {
match /conferences/{confid} {
allow read,write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confid)).data.admin;
}
}
}
模拟器出现以下错误:
使用不存在资源的路径调用的函数[get]:/ databases /%28default%29/29 / documents / conferences /%7Bconfid%7D
也在真实的设备上测试此操作,但我拒绝了访问。
但是,如果我像下面那样使用文档的ID,它可以工作并且可以访问。
service cloud.firestore {
match /databases/{database}/documents {
match /conferences/{confid} {
allow read,write: if request.auth.uid in get(/databases/$(database)/documents/conferences/ySWLb8NSTj9sur6n2CbS).data.admin;
}
}
}
显然,我无法为每个ID进行硬编码。
更新
除了在支持下记录该案例,我还进行了一些进一步的测试。 模拟器现在在下面授予访问权限。
service cloud.firestore {
match /databases/{database}/documents {
match /conferences/{confID}{
allow read, write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users;
}
}
}
作为参考,我使用以下内容从Web应用程序中查询:
db.collection("conferences")
.get()
.then(query => {
console.log("SUCCESS!!!")
query.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
}).catch((e) => {
console.log(e)
})
这是来自浏览器的日志:
FirebaseError:缺少权限或权限不足。 在新的FirestoreError(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:352:28) 在JsonProtoSerializer.fromRpcStatus(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:5649:16)中 在JsonProtoSerializer.fromWatchChange(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:6146:44) 在PersistentListenStream.onMessage(webpack-internal:///../node_modules/@firebase/firestore/dist/index.cjs.js:14350:43) 在评估时(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14279:30) 在评估时(webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14319:28) 在评估时(webpack-internal:///../node_modules/@firebase/firestore/dist/index.cjs.js:7411:20)
我正在使用最新的Firebase软件包5.8.3。
如果我将上述规则更改为类似下面的简单内容,只要我以用户身份登录,它就可以访问:
service cloud.firestore {
match /databases/{database}/documents {
match /conferences/{confID}{
allow read, write: if request.auth.uid != null
}
}
}
这甚至让我感到困惑。这是因为规则更复杂,验证时间太长,并且拒绝回访吗?
Update-2
通过Flutter在移动应用中对此进行了快速测试。结果相同。此规则集拒绝访问。
service cloud.firestore {
match /databases/{database}/documents {
match /conferences/{confID}{
allow read, write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users;
}
}
}
答案 0 :(得分:0)
我认为我的问题是查询的安全规则不匹配。如果只访问一个特定的文档,它将起作用,但是,如果您查询集合中的多个文档,则会被安全规则阻止。 我有两个选择。重组我的数据,以便一个文档可以容纳我需要的所有数据,或者重新设计安全规则以匹配查询的数据。 最后,我在每个文档上附加了一个标识符,例如UID,以确保查询与安全规则匹配。
答案 1 :(得分:0)
一种解决方案是将具有权限的用户放到会议文档的数组中,
所以request.resource.data.permissions
所以,代替这个:
get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users
使用此:
request.resource.data.permissions
这不能解决get()
问题,但可以消除对get()
通话的需求,这样可以节省15%或更多的配额。