Flutter Firebase工厂构造函数及Object转Map类型报错问题
问题修复方案
两个报错的根因和修复方式如下:
- 第一个报错:
_patientFromJson和_patientToJson被定义为类的实例方法,实例方法需要类实例化之后才能调用,但工厂构造函数运行时还没有生成类实例,自然访问不到。把两个方法改成类的静态方法即可,静态方法归属类本身,不需要实例就能调用。 - 第二个报错:cloud_firestore 2.0及以上版本中,
DocumentSnapshot.data()的返回值类型是Object?,不再默认返回Map<String, dynamic>,手动做一次类型强转即可匹配参数类型。
另外原有代码里还有两个隐藏问题:
_patientFromJson传参顺序和构造函数定义的参数顺序不一致,会导致birth和genre字段数据错位- Firestore存储的时间字段是
Timestamp类型,直接赋值给DateTime类型的属性会触发类型错误,需要做一次类型转换。
修复后的完整可运行代码:
import 'package:cloud_firestore/cloud_firestore.dart'; class Patient { String? name; String? pass; String? image; String? genre; DateTime? birth; DocumentReference? reference; Patient( this.name, this.pass, this.genre, this.birth, { this.reference, }); factory Patient.fromSnapshot(DocumentSnapshot snapshot) { // 强转data类型,解决第二个报错 final snapshotData = snapshot.data()! as Map<String, dynamic>; Patient newPatient = Patient.fromJson(snapshotData); newPatient.reference = snapshot.reference; return newPatient; } factory Patient.fromJson(Map<String, dynamic> json) => _patientFromJson(json); Map<String, dynamic> toJson() => _patientToJson(this); @override String toString() => 'name $name'; // 改为静态方法,解决第一个报错 static Patient _patientFromJson(Map<String, dynamic> data) { return Patient( data['name'] as String?, data['pass'] as String?, data['genre'] as String?, // Firestore Timestamp 转 DateTime (data['birth'] as Timestamp?)?.toDate(), ); } // 改为静态方法,解决第一个报错 static Map<String, dynamic> _patientToJson(Patient instance) { return { 'name': instance.name, 'pass': instance.pass, 'birth': instance.birth, 'genre': instance.genre, }; } }
内容的提问来源于stack exchange,提问作者nullonprog
相关产品推荐
相关产品推荐

