如果允许用户根据用户的电子邮件地址阅读文档中的文档,我想存储。多个用户应该可以访问同一个文档。
根据the documentation,Firestore不允许查询数组成员。这就是为什么我将用户电子邮件地址存储在String-Bool地图中,并将电子邮件地址作为密钥。
对于以下示例,我没有将电子邮件用作地图密钥,因为它已经不能使用基本字符串。
数据库结构如下所示:
lists
list_1
id: String
name: String
owner: E-Mail
type: String
shared:
test: true
此处列出了所有安全规则:
service cloud.firestore {
match /databases/{database}/documents {
match /lists/{listId=**} {
allow read: if resource.data.shared.test == true
}
}
}
修改:如果我使用match /lists/{listId}
代替match /lists/{listId=**}
我如何理解,如果地图shared[test]
中的值为真,此安全规则应允许读取所有人的访问权限。
为了完整性:这是我使用的查询(Android上的Kotlin):
collection.whereEqualTo("shared.test", true).get()
.addOnCompleteListener(activity, { task ->
if (task.isSuccessful) {
Log.i("FIRESTORE", "Query was successful")
} else {
Log.e("FIRESTORE", "Failed to query existing from Firestore. Error ${task.exception}")
}
})
我猜测我无法访问安全规则中的地图值。那么什么是我的问题的替代解决方案?
在Firestore rules reference中写道,可以像resource.data.property == 'property'
一样访问地图,那么我做错了什么?
答案 0 :(得分:9)
修改:此问题现在应该修复。如果您仍然看到它(并且确定它是规则评估者的错误),请在评论中告诉我。
我在这里与一些人讨论过您遇到的问题,这似乎是安全规则本身的问题。从本质上讲,问题似乎特定于评估查询中的嵌套字段,例如您正在做的事情。
因此,基本上,您正在做的事情应该可以正常工作,并且您需要等待Firestore团队的更新才能使此查询正常工作。当发生这种情况时,我会记得更新这个答案。很抱歉'回合!
答案 1 :(得分:0)
无论何时具有(可选)嵌套属性,都应先确保该属性存在,然后再继续检查其值,例如。
allow read: if role in request.auth.token && request.auth.token[role] == true
根据您的情况:
allow read: if test in resource.data.shared && resource.data.shared.test == true
,我在角色上挣扎了很长时间,直到我意识到在非管理员用户上admin字段是未定义的,并且Firestore规则崩溃了,并且不再继续检查其他可能的匹配项。
对于没有token.admin的用户,这将总是崩溃,无论您是否有其他匹配的匹配项,例如:
function userHasRole(role) {
return isSignedIn() && request.auth.token[role] == true
}