dew*_*ald 5 firebase firebase-security flutter google-cloud-firestore
我有一个 Flutter 应用程序,用户可以在其中发布帖子并将帖子标记为属于一个组。帖子存储在一个全局集合中,每个帖子都有一个Post.groupId字段:
/posts/{postId}
Run Code Online (Sandbox Code Playgroud)
根据我的 Firestore 安全规则和查询,如果用户在帖子被标记的组(即帖子的groupId字段)中,则只允许他们阅读帖子。批准的组用户存储在:
/groups/{groupId}/users/{userId}
Run Code Online (Sandbox Code Playgroud)
我可以查询来自特定用户组的帖子,例如:
_firestore.collection('posts').where('groupId', isEqualTo: 'groupA')...
Run Code Online (Sandbox Code Playgroud)
以上这些都正常工作。
我正在尝试进行改进,其中可以在多个组中而不是一个组中标记帖子,因此我将单个Post.groupId字段替换为Post.groupIds数组。如果用户是来自 的任何组的成员,则他/她应该能够阅读帖子Post.groupIds。我尝试使用 Flutter 应用程序中的以下查询阅读所有标记为特定组的帖子:
_firestore.collection('posts').where('groupIds', arrayContains: 'groupA')...
Run Code Online (Sandbox Code Playgroud)
Missing or insufficient permissions对于这些安全规则,我不断收到以下异常:
match /posts/{postId} {
allow read: if canActiveUserReadAnyGroupId(resource.data.groupIds);
}
function isSignedIn() {
return request.auth != null;
}
function getActiveUserId() {
return request.auth.uid;
}
function isActiveUserGroupMember(groupId) {
return isSignedIn() &&
exists(/databases/$(database)/documents/groups/$(groupId)/users/$(getActiveUserId()));
}
function canActiveUserReadAnyGroupId(groupIds) {
return groupIds != null && (
(groupIds.size() >= 1 && isActiveUserGroupMember(groupIds[0])) ||
(groupIds.size() >= 2 && isActiveUserGroupMember(groupIds[1])) ||
(groupIds.size() >= 3 && isActiveUserGroupMember(groupIds[2])) ||
(groupIds.size() >= 4 && isActiveUserGroupMember(groupIds[3])) ||
(groupIds.size() >= 5 && isActiveUserGroupMember(groupIds[4]))
);
}
Run Code Online (Sandbox Code Playgroud)
有了这些安全规则,我可以阅读一篇文章,但无法进行上述查询。是否有允许我进行此查询的安全规则?
更新 1
新增isSignedIn()和getActiveUserId()对完整性的安全规则的功能。
更新 2
这是我尝试在本地使用 Firestore 模拟器执行此查询时收到的错误:
FirebaseError:
Function not found error: Name: [size]. for 'list' @ L215
Run Code Online (Sandbox Code Playgroud)
第 215 行对应allow read于此规则中的行:
match /posts/{postId} {
allow read: if canActiveUserReadAnyGroupId(resource.data.groupIds);
}
Run Code Online (Sandbox Code Playgroud)
如果我不得不猜测,我会说 groupIds 实际上不是 List 类型对象,这意味着文档中的字段也不是数组。如果它是字符串,则此代码将不起作用,因为字符串没有size()在规则语言中调用的方法。
如果您不能 100% 确定字段的类型,则需要检查规则中的类型并确定如何处理它。您可以使用is运算符来检查类型。例如,groupIds is list如果您实际上正在使用它,则将是布尔值 true。
在您的规则中,您可以使用该debug()函数将某些表达式的值转储到日志中。它将返回相同的值。因此,您可以说debug(groupIds) != null打印该值并检查它是否为空。
| 归档时间: |
|
| 查看次数: |
2380 次 |
| 最近记录: |