据我了解,Firestore不允许在类型为array的字段中进行查询,这很可惜。因此,如果希望能够查询数组的内容,则必须将一个字段设置为对象类型,然后将这些字段设置为地图,这称为嵌套地图。我想要一张地图,其中的钥匙是另一个用户的ID。因此,数据库结构为:
database
users
{userId}
friends
userId1: true
userId2: true
“ userId1”和“ userId2”字段名称会根据列出为朋友的人的userId有所不同。
问题是,如何编写我的安全规则,以便我可以找到我的文档(通过我的{userId})和其他用户的文档,而我的{userId}是另一个用户的“朋友”对象中的字段用户的文档?
我想应该是这样的。
match /users/{userId} {
allow read, update, delete: if resource.data.userId == request.auth.uid;
allow read: if resource.data.friends.{userId} == true;
}
但是这当然不起作用,因为您似乎无法使用变量{userId}来命名要对其进行测试的字段。因此,如果无法做到这一点,那么如何搜索文档并将我的{userId}以某种方式存储在其他人的文档中?
编辑
好吧,我想我已经确定了规则(见下文)。但是,当尝试测试这些规则时,我似乎无法编写Swift调用来基于该friends对象检索数据。我的Swift电话是:
db.collection("users").whereField(FieldPath(["friends.\(userId)"]), isEqualTo: true)
所以,我的问题是:
如何进行Swift调用以在对象类型的字段名称中查找具有特定userId的人员?
服务cloud.firestore {
匹配/ databases / {database} / documents {
匹配/ users / {documentId} {
允许读写:if isOwner();
允许读取:如果getFriend(request.auth.uid)== true;
function isOwner() {
return request.auth.uid == resource.auth.uid;
}
function getFriend(userId) {
return getUserData().friends[userId]
}
function getUserData() {
return get(/databases/$(database)/documents/rooms/{documentId}).data
}
}
}
}
答案 0 :(得分:1)
我仍然没有解决访问对象中字段的问题,但是请注意,我的安全规则通常无效。例如,您不能有多行具有相同的规则类型,也不能有多行带有“ allow:read”。您必须使用&&和||。例如,如果要检查两件事,则基本规则的正确定义是:
// Database rules
service cloud.firestore {
// Any Cloud Firestore database in the project.
match /databases/{database}/documents {
// Handle users
match /users/{documentId} {
// The owner can do anything, you can access public data
allow read: if (isOwner() && isEmailVerified()) || isPublic();
allow write: if isOwner() && isEmailVerified();
// Functions //
function isSignedIn() {
return request.auth != null;
}
function isOwner() {
return request.auth.uid == resource.data.userId;
}
function isPublic() {
return resource.data.userId == "public";
}
function isEmailVerified() {
return request.auth.token.email_verified
}
}
}
}