You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正Dart/Flutter中Freezed库嵌套类toJson转换错误问题

问题原因

Freezed 依赖的 json_serializable 库默认explicit_to_json参数为false,这种配置下序列化嵌套的自定义类时,不会自动调用嵌套类的toJson方法,只会直接调用嵌套类的toString()方法输出字符串,就是你遇到的情况。

修复方案

两种实现方式二选一即可:

方式1:全局配置(推荐,项目所有类生效)

  1. 打开项目根目录的pubspec.yaml文件,添加如下配置:
targets:
  $default:
    builders:
      json_serializable:
        options:
          explicit_to_json: true
  1. 终端运行命令重新生成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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 21:18:03