在我使用Firebase模拟器的本地环境中,我有以下规则会引发FirebaseError: Property managers is undefined on object. for 'list'
:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /businesses/{business} {
allow read: if request.auth != null && request.auth.uid in resource.data.managers;
}
}
}
如果我在规则游乐场测试相同的规则,它将正常工作(Simulated read allowed
..]
为了证明我已经定义并可用了managers属性,如果将规则更改为if true
,则可以使用以下本地数据在列表上循环:
// code
...
.then((snap) => snap.forEach((doc) => console.log(doc.id, " => ", doc.data())))
// output
VzaU8rX8HOgejk0fyOFK => {..., managers: Array(1)}
我在做什么错?
谢谢!
UPDATE
这是我希望对其应用规则的代码:
useEffect(() => {
db.collection("businesses")
.where("slug", "==", params.slug)
.get()
.then((snap) => {
if (!snap.empty) {
// slug is supposed to be unique, so I retrieve the first and only element
const doc = snap.docs[0]
setBusiness({ id: doc.id, data: doc.data() })
setState({ ...state, loading: false, data: true })
} else {
setState({ ...state, loading: false, error: "Business not found" })
}
})
.catch((error) => {
console.log("Error getting document:", error)
setState({ ...state, loading: false, error: "Error getting document" })
})
}, [])
您的规则在控制台模拟器中有效,因为它一次仅测试单个文档的读取。但是,您的客户代码正在查询多个文档,这是不同的。要知道的一件非常重要的事情是security rules are not filters(一定要读一下,然后再读this)。如果安全规则拒绝文档,则安全规则不会从结果集中删除文档。相反,查询必须能够提取规则允许的所有文档,否则规则将完全拒绝查询。
查询必须具有与规则所要求的过滤器相同的过滤器。您的规则要求查询仅过滤当前用户在managers数组字段中的文档。因此,查询必须更像这样:
db.collection("businesses")
.where("slug", "==", params.slug)
.where("managers", "array-contains", uid)
uid
是当前用户的uid。
起初,您可以尝试db.collection("businesses").get("VzaU8rX8HOgejk0fyOFK");
吗?
第二,您是否将array-contains
,in
或array-contains-any
用作where()
方法比较操作?
如果没有,请尝试以下代码吗?
例如
db.collection("businesses").where("managers", "in", uid)
.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.id, " => ", doc.data());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});