While working with Firebase Firestore, I am coming across the following error:

E/flutter ( 4477): [ERROR:flutter/shell/common/shell.cc(93)] Dart Unhandled Exception: type 'Future<Group>' is not a subtype of type 'Group', stack trace: #0      new List.from (dart:core-patch/array_patch.dart:41:5)
E/flutter ( 4477): #1      GroupService.getGroups (package:money_manager/core/services/group_service.dart:56:21)
E/flutter ( 4477): <asynchronous suspension>
E/flutter ( 4477): #2      GroupViewModel._getAllGroups (package:money_manager/core/view_models/group_viewmodel.dart:44:26)
E/flutter ( 4477): <asynchronous suspension>
E/flutter ( 4477):

Though I think I have made proper use of async-await wherever necessary, I am not being able to figure out this error. Relevant code:

in group-service.dart :

Future<List<Group>> getGroups() async {
    final userData = await getUserData();
    List<Group> groups = [];

    if (userData['groups'] != null) {
      List<String> groupIds = List.from(userData['groups'].map((e) => e['id']));
      groups = List.from(groupIds.map((e) async {
        return await getGroupFromId(e);
      }));
    }

    return groups;
  }

  Future<Group> getGroupFromId(String groupId) async {
    final groupData = await getGroupData(groupId);
    return Group.fromJson(groupData);
  }

  Future<Map<String, dynamic>> getGroupData(String groupId) async {
    DocumentReference groupDoc =
        FirebaseFirestore.instance.collection('groups').doc(groupId);
    final snapshot = await groupDoc.get();
    Map<String, dynamic> groupData = snapshot.data() as Map<String, dynamic>;
    return groupData;
  }

in group_viewmodel.dart:

List<Group> _userGroups = [];
 void _getAllGroups() async {
    List<Group> groups = await _groupService.getGroups();
    _userGroups = groups;
  }

推荐答案

The problem is in the following line:

groups = List.from(groupIds.map((e) async {
   return await getGroupFromId(e);
}));

Even though you're using await before the return of the map() function, it will still return a Future. map() is a synchronous function, and it doesn't run the inner function asynchronously. Thus, it will return an Iterable<Future<Group>>, which fails to be converted into a List<Group> in the List.from() function.

There is a handy function that takes an iterable of futures and waits for each one of them, Future.wait(). Here's how your code will look like with it:

groups = List.from(await Future.wait(groupIds.map((e) async {
   return await getGroupFromId(e);
})));

And even better with tear-offs:

groups = List.from(await Future.wait(groupIds.map(getGroupFromId)));

Flutter相关问答推荐

如何在不使用NULL-check(!)的情况下缩小`FutureBuilder.Builder()`内部的`Snaphot`范围

使用自定义控制器将项插入到ListView中时行为不正确

在保持标高=1的情况下更改AppBar立面 colored颜色 /遮罩

在Fighter中,我如何在窗口的顶部和底部排列Widget?

Flutter 蜂巢不能正常工作,我正在使用蜂巢在设备上存储数据,但当我关闭并重新启动应用程序时,我失go 了一切

在VSCode中运行应用程序而不进行调试时,控制台仍显示为调试模式

Flutter 渲染HTML和数学(LaTeX和Katex)

在带有 flutter 的 Native Android 中,EventChannel.EventSink 始终为 null

没有固定宽度的小部件可以约束文本小部件吗?

GridView 渲染项目之间有微小的间隙

模块是使用不兼容的 kotlin 版本编译的.其元数据的二进制版本是1.8.0,预期版本是1.6

如何从Firebase登录获取用户信息,如电话号码、出生日期和性别

用户文档 ID 与 Firestore 中的用户 ID 相同

如何解决需要一个标识符,但得到的是:.try 在:之前插入一个标识符.dart 错误

有没有办法在没有收缩包装的情况下在列中使用 ListView.Builder?

减少 Flutter 中 API 的连接等待时间

如何扫描来自给定链接或按钮的重定向中的所有 URL?

Pub get 尚未运行

Flutter 如何要求用户在应用程序中设置电话密码?

如何在椭圆形图像周围添加边框?Flutter