Flutter 未处理的异常:类型 'Future<Group>' 不是类型 'Group' 的子类型
Flutter Unhandled Exception: type 'Future<Group>' is not a subtype of type 'Group'
在使用 Firebase Firestore 时,我遇到了以下错误:
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):
虽然我认为我已经在必要时正确使用了 async-await,但我无法找出这个错误。相关代码:
在 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;
}
在 group_viewmodel.dart
中:
List<Group> _userGroups = [];
void _getAllGroups() async {
List<Group> groups = await _groupService.getGroups();
_userGroups = groups;
}
问题出在以下行:
groups = List.from(groupIds.map((e) async {
return await getGroupFromId(e);
}));
即使您在 map()
函数的 return
之前使用 await
,它仍然会 return 一个 Future
。 map()
是一个同步函数,它不异步 运行 内部函数。因此,它将return一个Iterable<Future<Group>>
,在List.from()
函数中无法转换为List<Group>
。
有一个方便的函数,它接受可迭代的未来并等待它们中的每一个,Future.wait()
。以下是您的代码使用它后的样子:
groups = List.from(await Future.wait(groupIds.map((e) async {
return await getGroupFromId(e);
})));
tear-offs 更好:
groups = List.from(await Future.wait(groupIds.map(getGroupFromId)));
在使用 Firebase Firestore 时,我遇到了以下错误:
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):
虽然我认为我已经在必要时正确使用了 async-await,但我无法找出这个错误。相关代码:
在 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;
}
在 group_viewmodel.dart
中:
List<Group> _userGroups = [];
void _getAllGroups() async {
List<Group> groups = await _groupService.getGroups();
_userGroups = groups;
}
问题出在以下行:
groups = List.from(groupIds.map((e) async {
return await getGroupFromId(e);
}));
即使您在 map()
函数的 return
之前使用 await
,它仍然会 return 一个 Future
。 map()
是一个同步函数,它不异步 运行 内部函数。因此,它将return一个Iterable<Future<Group>>
,在List.from()
函数中无法转换为List<Group>
。
有一个方便的函数,它接受可迭代的未来并等待它们中的每一个,Future.wait()
。以下是您的代码使用它后的样子:
groups = List.from(await Future.wait(groupIds.map((e) async {
return await getGroupFromId(e);
})));
tear-offs 更好:
groups = List.from(await Future.wait(groupIds.map(getGroupFromId)));