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

如何用json_serializable为PerFieldToJson生成父类category字段方法?

解决Firestore ODM生成代码缺失父类字段的问题

问题根源

_$FooPerFieldToJson只生成子类Foo的age字段,是因为父类Bar未被@JsonSerializable注解标记,导致依赖json_serializable实现字段映射的Firestore ODM代码生成器,无法识别父类的category字段,进而不会将其纳入perFieldToJson和字段映射逻辑中。

解决方案

要让父类字段被生成器识别,需完成以下步骤:

1. 为父类Bar添加序列化配置

给Bar类添加@JsonSerializable注解,并声明对应的part文件,让json_serializable为它生成序列化代码:

// bar.dart
import 'package:json_annotation/json_annotation.dart';

part 'bar.g.dart';

@JsonSerializable()
abstract class Bar {
  final String category;
  Bar({required this.category});

  // 声明序列化方法,触发生成器处理父类字段
  factory Bar.fromJson(Map<String, dynamic> json) => _$BarFromJson(json);
  Map<String, dynamic> toJson() => _$BarToJson(this);
}

2. 修改子类Foo的序列化配置

在Foo的@JsonSerializable中添加useSuperKeys: true,确保生成器将父类字段纳入子类逻辑;同时声明子类的序列化方法并关联父类逻辑:

// foo.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:cloud_firestore_odm/cloud_firestore_odm.dart';
import 'package:json_annotation/json_annotation.dart';
import 'bar.dart';

part 'foo.g.dart';

@JsonSerializable(
  createFieldMap: true,
  createPerFieldToJson: true,
  useSuperKeys: true, // 关键:启用父类字段的序列化支持
)
class Foo extends Bar {
  final int age;
  Foo(this.age) : super(category: 'c');

  // 生成子类序列化方法,关联父类逻辑
  factory Foo.fromJson(Map<String, dynamic> json) => _$FooFromJson(json);
  @override
  Map<String, dynamic> toJson() => _$FooToJson(this);
}

@Collection<Foo>('foo')
final fooRef = FooCollectionReference();

3. 重新执行代码生成命令

运行dart run build_runner build -d,此时生成的foo.g.dart中,_$FooPerFieldToJson会包含category字段的处理方法:

// foo.g.dart
abstract class _$FooPerFieldToJson {
  // ignore: unused_element
  static Object? age(int instance) => instance;
  // ignore: unused_element
  static Object? category(String instance) => instance;
}

同时whereCategory方法中的_$FooPerFieldToJson.category()调用也能正常工作,不会再报错。

补充说明

  • useSuperKeys: true是让json_serializable将父类字段纳入子类字段映射和序列化逻辑的核心配置。
  • 父类必须显式声明fromJson和toJson方法,否则生成器无法为父类生成对应的序列化代码,子类也无法继承处理父类字段。

内容的提问来源于stack exchange,提问作者iDecode

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:55:15