You need to enable JavaScript to run this app. Freezed结合json_serializable时如何正确配置使用自定义Converter
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 08:36:03