繁体   English   中英

在 FLutter 中加入两个 Firestore collections

[英]Join two firestore collections in FLutter

我在 Firestore 中有两个 collections。 其中一个是“用户” ,另一个是“团队” 现在它们的 uid 与列表“teamMembersUid”“teamsMemberUid”相关,如您在代码中所见:

class UserModel {
  String? uid;
  String? email;
  String? firstName;
  String? secondName;
  String? userName;
  String? teamSelected;
  List<String>? teamsMemberUid;
  List<String>? notifications;


class TeamModel {
  String? uid;
  String? teamName;

  List<String>? teamMembersUid;
  List<UserModel>? teamMembers;
  List<String>? publicationsUid;
  List<String>? notifications;
  List<String>? instancesUid;

我想创建一个应用程序 state ,它是登录用户所属的团队列表 在每个团队中,我想要一个属于该团队的每个用户及其信息(teamMembers)的列表 我想在本地获取该信息,不要将其上传到 Firestore。 我一直在尝试创建的 function 是这样的:

Future<List<TeamModel>> getTeamsWithUsersInfo(String? userUid) async {
    List<TeamModel> retVal = [];
    try {
      //Create a list with the teams to which the user belongs from firestore
      final data = await _firestore
          .collection("teams")
          .where("teamMembersUid", arrayContains: userUid)
          .get();
      List<TeamModel> data_m =
          List.from(data.docs.map((doc) => TeamModel.fromMap(doc)));  
      //Fill teamMembers list with users information
      data_m.forEach((element) async {
        await getTeamUsersInfo(element.teamMembersUid!)
            .then((List<UserModel> users) {
          element.teamMembers = users;
          retVal.add(element);
        });
      });    
    } catch (e) {
      print(e);
    }
    return retVal;
  }

getTeamUserInfo function 是这样的:

Future<List<UserModel>> getTeamUsersInfo(List<String> teamMembersUid) async {
    List<UserModel> retVal = [];

    teamMembersUid.forEach((element) async {
      await getUserInfo(element).then((userData) => retVal.add(userData));
    });
    return retVal;
  }

getUserInfo function 是这样的:

Future<UserModel> getUserInfo(String uid) async {
    UserModel retVal = UserModel();
    try {
      DocumentSnapshot _docSnapshot =
          await _firestore.collection('users').doc(uid).get();
      retVal = UserModel.fromMap(_docSnapshot);
      return retVal;
    } catch (e) {
      print(e);
    }
    return retVal;
  }

在调试模式下,我可以看到 getTeamUsersInfo 获取不同团队的用户列表,但它发生在 getTeamWithUsersInfo output 团队列表之后,其中 teamMembers 字段为空,因此在执行 getTeamUsersInfo 后,ZC1C425268E68385D1ABZ5074C17A94F1 已执行再次。

您是否在代码中看到任何错误或可疑之处? 你知道在 Firestore 中加入更有效的方法吗?

我有几件事可以检查/改进

  1. 您没有等待这个,因此该过程将继续进行而不等待结果: data_m.forEach((element) async {

  2. 不要将awaitthen结合起来: await getTeamUsersInfo(element.teamMembersUid.).then Check this SO answer

  3. 不要像你一样使用forEach-async组合。 检查这个SO 答案

您可以尝试:

await Future.forEach(data_m, (element) async {
  final users = await getTeamUsersInfo(element.teamMembersUid!);
  element.teamMembers = users;
  retVal.add(element);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM