通过Flutter以基于角色的安全性查询Firestore文档



根据谷歌的建议,我在Firestore上有一个基于角色的数据模型:https://firebase.google.com/docs/firestore/solutions/role-based-access

安全规则设置正确,运行良好。但现在我遇到了如何查询角色的问题。

这是我的数据模型(一个示例文档):

id: "1234-5678-91234",
roles:
userId_1:"owner",
userId_2:"editor
title: "This is a sample document"

这是我在Flutter中的Firestore查询,如果用户为文档分配了角色"所有者">的话,它会通过ID获取特定用户的所有文档:

return firestore
.collection(path)
.where("roles.${user.firebaseUserId}", isEqualTo: "owner")
.snapshots().map((snapshot) {
return snapshot.documents.map((catalog) {
return SomeDocumentObject(...);
}).toList();
});

我现在的问题是,我需要某种"OR"子句——据我所知,这种子句并不存在以上查询仅检索角色为"所有者"的用户的文档,但如果用户ID与角色"编辑器"关联,则我需要一个同时检索文档的查询

我试过"arrayContainers",但似乎也不起作用(因为它是一张地图)。

我读过关于使用两个独立查询的解决方案的文章,由于开销很大,这听起来不是一个好的解决方案。

也许你们中的某个人对我有什么暗示?:)

谢谢&最好的Michael

Firestore当前没有任何逻辑OR运算。您必须执行两个查询,每个条件一个,并在客户端应用程序中合并两个查询的结果。

这是使用RxDartObservables.combineLatest()最终解决方案-也许它可以帮助其他人:

@override
Stream<List<Catalog>> catalogs(User user) {
// Retrieve all catalogs where user is owner
Observable<QuerySnapshot> ownerCatalogs = Observable(firestore
.collection(path)
.where("roles.${user.firebaseUserId}", isEqualTo: "owner")
.snapshots());
// Retrieve all catalogs where user is editor
Observable<QuerySnapshot> editorCatalogs = Observable(firestore
.collection(path)
.where("roles.${user.firebaseUserId}", isEqualTo: "editor")
.snapshots());
// Convert merged stream to list of catalogs
return Observable.combineLatest([ownerCatalogs, editorCatalogs],
(List<QuerySnapshot> snapshotList) {
List<Catalog> catalogs = [];
snapshotList.forEach((snapshot) {
snapshot.documents.forEach((DocumentSnapshot catalog) {
catalogs.add(Catalog(
id: catalog.documentID,
title: catalog.data['title'],
roles: catalog.data['roles'],
));
});
});
return catalogs;
}).asBroadcastStream();
}