Flutter空安全迁移中Firebase的snapshot.data()类型不匹配报错如何处理
问题产生原因
空安全版本的FlutterFire库对DocumentSnapshot的data()方法做了类型调整:
- 旧版本默认返回
Map<String, dynamic>类型 - 新版本返回
Object?类型,既没有默认Map类型声明,也增加了空值标识
你的代码直接将data()返回值传入要求Map<String, dynamic>类型参数的fromMap方法,类型不匹配触发编译错误:
The argument type 'Object?' can't be assigned to the parameter type 'Map<String, dynamic>'.
解决办法
方案1:直接显式类型转换(简单快捷)
在fromSnapshot方法内对snapshot.data()做强制类型转换即可,如果你确认文档一定存在数据,可以直接写:
UserModel.fromSnapShot(DocumentSnapshot snapshot) : this.fromMap( snapshot.data() as Map<String, dynamic>, snapshot.id, reference: snapshot.reference );
如果存在文档无数据的场景,可以增加空值兜底逻辑:
UserModel.fromSnapShot(DocumentSnapshot snapshot) : this.fromMap( (snapshot.data() ?? <String, dynamic>{}) as Map<String, dynamic>, snapshot.id, reference: snapshot.reference );
方案2:泛型声明指定类型(更规范,适合整体项目适配)
你在获取DocumentSnapshot的上游代码中,就通过泛型指定文档数据类型,后续调用data()就不需要重复强转:
// 示例:获取用户文档流时提前指定泛型 Stream<DocumentSnapshot<Map<String, dynamic>>> userStream = FirebaseFirestore.instance .collection('users') .doc('你的用户ID') .withConverter( fromFirestore: (snapshot, options) => snapshot.data()!, toFirestore: (value, options) => value, ) .snapshots();
此时你拿到的DocumentSnapshot调用data()默认返回Map<String, dynamic>?类型,直接传入fromMap方法即可。
额外适配提示
如果你的模型类属性都是非空类型,建议在fromMap方法中给每个字段增加默认值兜底,避免空安全报错:
UserModel.fromMap(Map<String, dynamic> map, this.userKey, {this.reference}) : profileImg = map[KEY_PROFILEIMG] ?? '', username = map[KEY_USERNAME] ?? '默认用户名', email = map[KEY_EMAIL] ?? '', likedPosts = map[KEY_LIKEDPOSTS] ?? [], followers = map[KEY_FOLLOWERS] ?? 0, followings = map[KEY_FOLLOWINGS] ?? 0, myPosts = map[KEY_MYPOSTS] ?? [];
内容的提问来源于stack exchange,提问作者Kevin Yang
相关产品推荐
相关产品推荐

