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

如何在Flutter中用JSONSerializable处理Cloud Firestore嵌套字段与Workout集合

解决Workout集合的嵌套与Map序列化问题

针对Workout集合的嵌套结构和Map类型字段,我们可以通过拆解嵌套为子模型+JSONSerializable的嵌套序列化支持来解决,具体步骤如下:

1. 拆解嵌套结构,定义子模型

根据Workout集合的嵌套层级,先定义两个子模型来处理深层数据:

1.1 训练组模型(WorkoutSet)

对应每个练习下的单组记录:

@JsonSerializable()
class WorkoutSet {
  final double weight;
  final int reps;
  final bool completed;

  WorkoutSet({
    required this.weight,
    required this.reps,
    required this.completed,
  });

  factory WorkoutSet.fromJson(Map<String, dynamic> json) => _$WorkoutSetFromJson(json);
  Map<String, dynamic> toJson() => _$WorkoutSetToJson(this);
}

1.2 训练项模型(WorkoutExercise)

对应Workout中关联的单个Exercise及其所有训练组数据:

@JsonSerializable()
class WorkoutExercise {
  final List<WorkoutSet> sets;

  WorkoutExercise({required this.sets});

  factory WorkoutExercise.fromJson(Map<String, dynamic> json) => _$WorkoutExerciseFromJson(json);
  Map<String, dynamic> toJson() => _$WorkoutExerciseToJson(this);
}

2. 定义Workout主模型

处理Firestore Timestamp与Dart DateTime的转换,同时支持Map类型的exercises字段(键为exerciseId,值为对应训练项数据):

@JsonSerializable()
class Workout {
  final String id;
  final String userId;
  final String name;
  // 自定义转换Firestore Timestamp和Dart DateTime
  @JsonKey(fromJson: _timestampToDateTime, toJson: _dateTimeToTimestamp)
  final DateTime date;
  // 动态键Map:键为exerciseId,值为WorkoutExercise实例
  final Map<String, WorkoutExercise> exercises;

  Workout({
    this.id = '',
    required this.userId,
    required this.name,
    required this.date,
    required this.exercises,
  });

  // Timestamp转DateTime
  static DateTime _timestampToDateTime(Timestamp timestamp) {
    return timestamp.toDate();
  }

  // DateTime转Timestamp
  static Timestamp _dateTimeToTimestamp(DateTime dateTime) {
    return Timestamp.fromDate(dateTime);
  }

  factory Workout.fromJson(Map<String, dynamic> json) => _$WorkoutFromJson(json);
  Map<String, dynamic> toJson() => _$WorkoutToJson(this);
}

3. 生成序列化代码

在终端执行命令,自动生成对应的.g.dart文件:

flutter pub run build_runner build

关键注意事项

  • 确保pubspec.yaml已添加依赖:
    dependencies:
      flutter:
        sdk: flutter
      cloud_firestore: ^latest_version
      json_annotation: ^latest_version
    
    dev_dependencies:
      build_runner: ^latest_version
      json_serializable: ^latest_version
    
  • 若Workout集合还有其他嵌套字段,按相同逻辑拆解为子模型即可;
  • 动态键Map(比如用户自定义的exerciseId)无需额外配置,Map<String, T>类型原生支持JSONSerializable序列化;
  • 空安全适配:如果Firestore中存在可空字段,需给模型字段添加?并在构造函数中设置默认值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:10:28