升级Flutter3后Map类型转换错误的解决方法咨询
问题描述
将Flutter升级至3版本,同时把Firebase及数据集更新到最新版本后,控制台出现错误提示:
type '_Map<Object?, Object?>' is not a subtype of type 'Map<String?, dynamic>' in type cast
错误出现在代码行:
itemId = (event.snapshot.value as Chat).itemId;
相关代码如下:
Chat类代码
class Chat extends MyObject<Chat?> { Chat({ this.itemId, this.receiverId, this.senderId, }); String? itemId; String? receiverId; String? senderId; @override bool operator ==(dynamic other) => other is Chat && itemId == other.itemId; @override int get hashCode => hash2(itemId.hashCode, itemId.hashCode); @override String? getPrimaryKey() { return itemId; } @override List<Chat?> fromMapList(List<dynamic> dynamicDataList) { final List<Chat?> subCategoryList = <Chat?>[]; for (dynamic dynamicData in dynamicDataList) { if (dynamicData != null) { subCategoryList.add(fromMap(dynamicData)); } } return subCategoryList; } @override Chat? fromMap(dynamic dynamicData) { if (dynamicData != null) { return Chat( itemId: dynamicData['itemId'], receiverId: dynamicData['receiver_id'], senderId: dynamicData['sender_id'], ); } else { return null; } } @override List<Map<String, dynamic>?> toMapList(List<Chat?> objectList) { final List<Map<String, dynamic>?> mapList = <Map<String, dynamic>?>[]; for (Chat? data in objectList) { if (data != null) { mapList.add(toMap(data)); } } return mapList; } @override Map<String, dynamic>? toMap(Chat? object) { if (object != null) { final Map<String, dynamic> data = <String, dynamic>{}; data['itemId'] = object.itemId; data['receiver_id'] = object.receiverId; data['sender_id'] = object.senderId; return data; } else { return null; } } }
MyObject抽象类代码
abstract class MyObject<T> { String? key = '0'; String? getPrimaryKey(); T fromMap(dynamic dynamicData); Map<String, dynamic>? toMap(T object); List<T> fromMapList(List<dynamic> dynamicDataList); List<Map<String, dynamic>?> toMapList(List<T> objectList); }
解决方案
核心问题
Firebase更新后,event.snapshot.value返回的类型从Map<String, dynamic>变为_Map<Object?, Object?>,直接将其强制转换为Chat类型本身逻辑错误——value是原始Map数据,必须通过Chat类的fromMap方法转换为对象,而非直接强转。
修复步骤
修正出错的代码行
替换错误的类型转换逻辑,先处理Map类型转换,再通过fromMap生成Chat对象:// 原错误代码 // itemId = (event.snapshot.value as Chat).itemId; // 修正后代码 final rawData = event.snapshot.value as Map<Object?, Object?>; final chat = Chat().fromMap(rawData.cast<String, dynamic>()); itemId = chat?.itemId;优化Chat类的fromMap方法
给方法参数添加明确的类型处理,避免后续类型警告:@override Chat? fromMap(dynamic dynamicData) { if (dynamicData != null) { // 将Map<Object?, Object?>安全转换为Map<String, dynamic> final castedData = (dynamicData as Map<Object?, Object?>).cast<String, dynamic>(); return Chat( itemId: castedData['itemId'], receiverId: castedData['receiver_id'], senderId: castedData['sender_id'], ); } else { return null; } }可选:简化抽象类泛型逻辑
如果业务允许,可调整MyObject的泛型参数为非空类型,减少可空处理的复杂度:// 修改抽象类 abstract class MyObject<T> { String? key = '0'; String? getPrimaryKey(); T fromMap(Map<String, dynamic> dynamicData); Map<String, dynamic> toMap(T object); List<T> fromMapList(List<Map<String, dynamic>> dynamicDataList); List<Map<String, dynamic>> toMapList(List<T> objectList); } // 修改Chat类继承及方法 class Chat extends MyObject<Chat> { // ... 其他属性、==、hashCode等代码不变 @override Chat fromMap(Map<String, dynamic> dynamicData) { return Chat( itemId: dynamicData['itemId'], receiverId: dynamicData['receiver_id'], senderId: dynamicData['sender_id'], ); } @override Map<String, dynamic> toMap(Chat object) { final Map<String, dynamic> data = <String, dynamic>{}; data['itemId'] = object.itemId; data['receiver_id'] = object.receiverId; data['sender_id'] = object.senderId; return data; } // 同步修改fromMapList和toMapList的参数与返回值类型 }
内容的提问来源于stack exchange,提问作者Vahit Behrouz
相关产品推荐
相关产品推荐

