未使用Firebase Firestore安全规则变量
为Firestore编写规则自定义变量似乎不起作用。 有人知道为什么或者见过类似的行为吗? 尽管uid在admin数组中,但使用下面的命令,访问被拒绝未使用Firebase Firestore安全规则变量,firebase,google-cloud-firestore,firebase-security,Firebase,Google Cloud Firestore,Firebase Security,为Firestore编写规则自定义变量似乎不起作用。 有人知道为什么或者见过类似的行为吗? 尽管uid在admin数组中,但使用下面的命令,访问被拒绝 service cloud.firestore { match /databases/{database}/documents { match /conferences/{confid} { allow read,write: if request.auth.uid in get(/database
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/documents/conferences/%7confid%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(网页包-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:352:28)
在JsonProtoSerializer.fromRpcStatus(网页包-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:5649:16)
在JsonProtoSerializer.fromWatchChange(网页包-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:6146:44)
在PersistentListenStream.onMessage(网页包-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14350:43)
评估时(网页)-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14279:30)
评估时(网页)-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14319:28)
评估时(网页)-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
}
}
}
这甚至让我更加困惑。这是因为规则更复杂,需要花费太长的时间来验证并返回拒绝访问的信息吗
更新-2
通过Flatter在移动应用程序中快速测试了这一点。同样的结果。使用此规则集拒绝访问
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;
}
}
}
我想我的问题是查询的安全规则不匹配。如果您只访问一个特定文档,那么它将起作用,但是如果您查询集合中的多个文档,则会被安全规则阻止。 我有两个选择。重新构造我的数据,使单个文档可以保存我需要的所有数据,或者重新设计安全规则以匹配查询。
最后,我在每个文档上都附加了一个标识符,如UID,以确保查询与安全规则匹配。我认为我的问题是查询与安全规则不匹配。如果您只访问一个特定文档,那么它将起作用,但是如果您查询集合中的多个文档,则会被安全规则阻止。 我有两个选择。重新构造我的数据,使单个文档可以保存我需要的所有数据,或者重新设计安全规则以匹配查询。
最后,我在每个文档上都附加了一个标识符,如UID,以确保查询符合安全规则。一个解决方案是将具有权限的用户放在会议文档中的一个数组中, 所以
request.resource.data.permissions
因此,与此相反:
get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users
使用以下命令:
request.resource.data.permissions
这并不能解决
get()
问题,但它可以消除调用get()
的需要,这可以为您节省15%或更多的配额。一个解决方案是将具有权限的用户放在会议文档中的数组中,
所以request.resource.data.permissions
因此,与此相反:
get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users
使用以下命令:
request.resource.data.permissions
这并不能解决
get()
问题,但它可以消除对get()
调用的需求,这可以为您节省15%或更多的配额。我以前从未遇到过使用变量的问题。它在一般意义上绝对没有坏。很高兴听到它在整体上没有坏。但我有点被困在这里进行故障排除。对发布的规则有什么建议吗?似乎另一个用户也经历了同样的问题,但也没有得到解决。如果您认为它已损坏,请联系Firebase支持,因为堆栈溢出可能对您没有帮助。当然开了一个案子。我很好奇支持部门会给出什么建议。我以前在使用变量时从来没有遇到过问题。它在一般意义上绝对没有坏。很高兴听到它在整体上没有坏。但我有点被困在这里进行故障排除。对发布的规则有什么建议吗?似乎另一个用户也经历了同样的问题,但也没有得到解决。如果您认为它已损坏,请联系Firebase支持,因为堆栈溢出可能对您没有帮助。当然开了一个案子。我想知道支持部门会提供什么建议。