Freezed结合json_serializable时如何正确配置使用自定义Converter
Freezed 类中 DateTime 与 Firebase Timestamp 序列化适配的修复方案
原有代码失效的核心原因
- 原自定义
JsonConverter实现的是非空DateTime与Timestamp的转换逻辑,但目标字段是可空的DateTime?:当源数据为null时,转换逻辑会直接触发类型不匹配异常 - json_serializable 对“直接标注在可空字段上的非空类型Converter”存在兼容识别问题,无法将转换规则正确绑定到生成的序列化代码中
- 未显式开启
explicitToJson配置,嵌套对象的序列化流程不会触发自定义Converter规则
具体优化步骤
1. 改造自定义Converter,兼容可空场景
将原Converter调整为支持可空值的实现,覆盖null值的转换逻辑,避免空值导致的类型错误:
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:json_annotation/json_annotation.dart'; class TimestampConverter implements JsonConverter<DateTime?, Timestamp?> { const TimestampConverter(); @override DateTime? fromJson(Timestamp? jsonValue) => jsonValue?.toDate(); @override Timestamp? toJson(DateTime? dateValue) => dateValue == null ? null : Timestamp.fromDate(dateValue); }
2. 调整Freezed类的注解配置
确保序列化规则正确绑定,可运行的完整类代码如下:
@freezed class NewsPost with _$NewsPost { // 显式开启嵌套对象的json序列化触发逻辑 @JsonSerializable(explicitToJson: true) factory NewsPost({ // 直接标注适配可空场景的Converter,需要自定义json key时保留@JsonKey即可 @JsonKey(name: "date") @TimestampConverter() DateTime? date, }) = _NewsPost; factory NewsPost.fromJson(Map<String, dynamic> json) => _$NewsPostFromJson(json); }
3. 重新生成绑定代码
旧的生成代码会残留之前的规则绑定,需要清理缓存后重新生成:
- 执行缓存清理命令:
flutter clean - 执行代码生成命令:
flutter pub run build_runner build --delete-conflicting-outputs
实用避坑提醒:
- 保持项目内
freezed、freezed_annotation、json_annotation、json_serializable的版本同步升级到最新稳定版,可解决大部分Converter不识别的兼容问题- 不要在同一个字段上同时配置多个作用重叠的序列化规则,避免规则优先级冲突
- 如果项目存在其他类型的时间源值(例如部分接口返回ISO格式字符串),可在Converter的
fromJson方法中扩展类型判断逻辑,兼容更多返回场景
内容的提问来源于stack exchange,提问作者Valentin Seehausen
相关产品推荐
相关产品推荐

