Firestore 可以读取 collection('users') 但不能读取 doc('users/{id}')
Firestore can read through collection('users') but not doc('users/{id}')
我正在使用 @react-native-firebase/firestore
我一定是在以错误的方式思考集合或文档,但我希望下面的安全规则能够阻止我通过 onSnapshot
获取文档,如果它们在直接通过 doc
但事实并非如此
// I get permission denied when doing this
firestore().doc('users/KRImYj0Lrmv00P9KRAuJ').get()
// I do not get permission denied when doing this and can access the document I can't get above
firestore().collection('users').onSnapshot()
安全规则
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{user} {
allow read: if resource.data.is_deleted == false
allow write: if false;
}
}
}
更新完整代码
// FIRST
try {
await firestore()
.collection('users')
.where('is_deleted', '==', true)
.onSnapshot((snapshot) => {
if (snapshot) {
snapshot.forEach((s) => {
console.log('User', s.data())
})
}
})
}
catch (error) {
console.log(error)
}
// SECOND
try {
const docs = await firestore()
.collection('users')
.where('is_deleted', '==', true)
.get()
console.log(docs)
}
catch (error) {
console.log(error)
}
第一个returns快照,我可以记录文档
FIRST LOGS
User {"fname": "Steve", "is_deleted": true, "lname": "Kaspar", "name": "Steven Kaspar", "name_change_count": 2}
User {"fname": "Brian", "is_deleted": true, "lname": "Fitz"}
SECOND LOGS
[Error: [firestore/permission-denied] The caller does not have permission to execute the specified operation.]
我怀疑在 onSnapshot
情况下,结果来自本地缓存,该缓存在您禁止读取操作之前已填充。
这是 onSnapshot
的正常行为:如果请求的文档在缓存中,它会立即触发,如果服务器上的文档不同,则可能会再次触发。由于安全规则仅在服务器上强制执行,因此如果缓存中有数据,第一个回调将始终发生。
另一方面,get()
调用立即 尝试从服务器获取文档。并且在您的情况下拒绝读取操作。您可以通过执行 get({ source: 'cache' })
来验证这一点,这将从缓存中读取文档,并且可能会成功,原因与 onSnapshot
相同。
我建议通过卸载并重新安装应用程序来清除本地缓存,这样它就不会包含用户(现在)不再有权访问的文档。
我正在使用 @react-native-firebase/firestore
我一定是在以错误的方式思考集合或文档,但我希望下面的安全规则能够阻止我通过 onSnapshot
获取文档,如果它们在直接通过 doc
但事实并非如此
// I get permission denied when doing this
firestore().doc('users/KRImYj0Lrmv00P9KRAuJ').get()
// I do not get permission denied when doing this and can access the document I can't get above
firestore().collection('users').onSnapshot()
安全规则
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{user} {
allow read: if resource.data.is_deleted == false
allow write: if false;
}
}
}
更新完整代码
// FIRST
try {
await firestore()
.collection('users')
.where('is_deleted', '==', true)
.onSnapshot((snapshot) => {
if (snapshot) {
snapshot.forEach((s) => {
console.log('User', s.data())
})
}
})
}
catch (error) {
console.log(error)
}
// SECOND
try {
const docs = await firestore()
.collection('users')
.where('is_deleted', '==', true)
.get()
console.log(docs)
}
catch (error) {
console.log(error)
}
第一个returns快照,我可以记录文档
FIRST LOGS
User {"fname": "Steve", "is_deleted": true, "lname": "Kaspar", "name": "Steven Kaspar", "name_change_count": 2}
User {"fname": "Brian", "is_deleted": true, "lname": "Fitz"}
SECOND LOGS
[Error: [firestore/permission-denied] The caller does not have permission to execute the specified operation.]
我怀疑在 onSnapshot
情况下,结果来自本地缓存,该缓存在您禁止读取操作之前已填充。
这是 onSnapshot
的正常行为:如果请求的文档在缓存中,它会立即触发,如果服务器上的文档不同,则可能会再次触发。由于安全规则仅在服务器上强制执行,因此如果缓存中有数据,第一个回调将始终发生。
另一方面,get()
调用立即 尝试从服务器获取文档。并且在您的情况下拒绝读取操作。您可以通过执行 get({ source: 'cache' })
来验证这一点,这将从缓存中读取文档,并且可能会成功,原因与 onSnapshot
相同。
我建议通过卸载并重新安装应用程序来清除本地缓存,这样它就不会包含用户(现在)不再有权访问的文档。