我在Google的建议下,在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通过其ID获取特定用户的所有文档:
return firestore
.collection(path)
.where("roles.${user.firebaseUserId}", isEqualTo: "owner")
.snapshots().map((snapshot) {
return snapshot.documents.map((catalog) {
return SomeDocumentObject(...);
}).toList();
});
现在我的问题是,我需要某种“ OR”子句-据我所知,该子句不存在。上面的查询仅为角色为“所有者”的用户检索文档< strong>但是我需要一个查询,如果userId与角色“编辑者”相关联,它也可以检索文档。
我尝试过“ arrayContains:”,它似乎也不起作用(因为它是一张地图)。
我已经阅读了有关带有两个独立查询的解决方案,由于开销很大,这听起来不是一个好的解决方案。
也许有人对我有暗示? :)
谢谢! 迈克尔
答案 0 :(得分:1)
Firestore当前没有任何逻辑或操作。您将必须执行两个查询,每个条件一个,然后在客户端应用程序中合并两个查询的结果。
答案 1 :(得分:0)
这是使用 RxDart , Observables 和 .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();
}