如何修正Dart/Flutter中Freezed库嵌套类toJson转换错误问题
问题原因
Freezed 依赖的 json_serializable 库默认explicit_to_json参数为false,这种配置下序列化嵌套的自定义类时,不会自动调用嵌套类的toJson方法,只会直接调用嵌套类的toString()方法输出字符串,就是你遇到的情况。
修复方案
两种实现方式二选一即可:
方式1:全局配置(推荐,项目所有类生效)
- 打开项目根目录的
pubspec.yaml文件,添加如下配置:
targets: $default: builders: json_serializable: options: explicit_to_json: true
- 终端运行命令重新生成Freezed代码:
flutter pub run build_runner build --delete-conflicting-outputs
方式2:单类单独配置
如果只需要给Person类开启嵌套序列化,不需要全局改动,在Person类的@freezed注解上方添加@JsonSerializable配置:
import 'package:adminapp/domains/Test/Profile.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:json_annotation/json_annotation.dart'; part 'Person.freezed.dart'; part 'Person.g.dart'; @JsonSerializable(explicitToJson: true) @freezed class Person with _$Person { factory Person({ String? id, Profile? profile, }) = _Person; factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json); }
修改后同样运行上面的build命令重新生成代码即可。
修复后效果
重新运行main.dart,输出的内容会变成标准嵌套JSON结构:
{id: 4, profile: {bDay: 2021-07-28 08:42:51.708857, hob: 123, rel: asd}}
额外补充(针对Firestore存储)
如果需要将DateTime类型直接存入Firestore,建议给DateTime字段添加序列化转换,避免默认的ISO字符串格式不符合Firestore Timestamp类型要求:
import 'package:cloud_firestore/cloud_firestore.dart'; @freezed class Profile with _$Profile { factory Profile({ @JsonKey(fromJson: _dateTimeFromTimestamp, toJson: _dateTimeToTimestamp) DateTime? bDay, String? hob, String? rel, }) = _Profile; factory Profile.fromJson(Map<String, dynamic> json) => _$ProfileFromJson(json); } // 转换方法 DateTime _dateTimeFromTimestamp(Timestamp timestamp) => timestamp.toDate(); Timestamp _dateTimeToTimestamp(DateTime date) => Timestamp.fromDate(date);
内容的提问来源于stack exchange,提问作者Yerbol Kistaubayev
相关产品推荐
相关产品推荐

