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

Flutter 通过flatter查询具有基于角色的安全性的Firestore文档,flutter,google-cloud-firestore,Flutter,Google Cloud Firestore,根据谷歌的建议,我在Firestore上有一个基于角色的数据模型: 安全规则设置正确,工作正常。但是现在我遇到了如何查询角色的问题 这是我的数据模型(一个示例文档): id: "1234-5678-91234", roles: userId_1:"owner", userId_2:"editor title: "This is a sample document" 这是颤振中的我的Firestore查询,如果用户为文档分配了角色“所有者”,则该查询将根据其ID获取特定用户的所有

根据谷歌的建议,我在Firestore上有一个基于角色的数据模型:

安全规则设置正确,工作正常。但是现在我遇到了如何查询角色的问题

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

id: "1234-5678-91234",
roles:
    userId_1:"owner",
    userId_2:"editor
title: "This is a sample document"
这是颤振中的我的Firestore查询,如果用户为文档分配了角色“所有者”,则该查询将根据其ID获取特定用户的所有文档:

return firestore
.collection(path)
.where("roles.${user.firebaseUserId}", isEqualTo: "owner")
.snapshots().map((snapshot) {
  return snapshot.documents.map((catalog) {
    return SomeDocumentObject(...);
  }).toList();
});
我现在的问题是,我需要某种“或”子句-据我所知,它并不存在。上面的查询只检索角色为“所有者”的用户的文档,但如果用户ID与角色“编辑器”相关联,我需要一个也检索文档的查询。

我尝试过“arrayContains:”这似乎也不起作用(因为它是一张地图)

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

也许你们中的某个人给了我一个提示?:)

谢谢&最好,
Michael

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

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

这是最终解决方案,使用RxDart可观测值.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();
  }
@覆盖
流目录(用户){
//检索用户为所有者的所有目录
可观测所有者目录=可观测(firestore
.集合(路径)
.where(“角色${user.firebaseUserId}”,isEqualTo:“所有者”)
.snapshots());
//检索用户正在编辑的所有目录
可观察的编辑目录=可观察的(firestore
.集合(路径)
.where(“角色${user.firebaseUserId}”,isEqualTo:“编辑器”)
.snapshots());
//将合并流转换为目录列表
返回可观察的.CombineTest([ownerCatalogs,editorCatalogs],
(列表快照列表){
列表目录=[];
snapshotList.forEach((快照){
snapshot.documents.forEach((DocumentSnapshot目录){
目录。添加(目录)(
id:catalog.documentID,
标题:catalog.data['title'],
角色:catalog.data['roles'],
));
});
});
返回目录;
}).asBroadcastStream();
}

这是最终解决方案使用RxDart可观测值和.CombineTest()-也许它能帮助某些人:

@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();
  }
@覆盖
流目录(用户){
//检索用户为所有者的所有目录
可观测所有者目录=可观测(firestore
.集合(路径)
.where(“角色${user.firebaseUserId}”,isEqualTo:“所有者”)
.snapshots());
//检索用户正在编辑的所有目录
可观察的编辑目录=可观察的(firestore
.集合(路径)
.where(“角色${user.firebaseUserId}”,isEqualTo:“编辑器”)
.snapshots());
//将合并流转换为目录列表
返回可观察的.CombineTest([ownerCatalogs,editorCatalogs],
(列表快照列表){
列表目录=[];
snapshotList.forEach((快照){
snapshot.documents.forEach((DocumentSnapshot目录){
目录。添加(目录)(
id:catalog.documentID,
标题:catalog.data['title'],
角色:catalog.data['roles'],
));
});
});
返回目录;
}).asBroadcastStream();
}

谢谢,这正是我所期望的——太悲伤了:)谢谢,这正是我所期望的——太悲伤了:)