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

Flutter中用Freezed+Firebase处理GeoPoint序列化构建报错求助

解决Freezed结合Firebase GeoPoint的JSON序列化问题

针对你用Freezed+Firebase处理GeoPoint时遇到的构建错误,这里提供一套可行的解决方案:

1. 编写GeoPoint专用JsonConverter

创建一个转换器类,负责GeoPoint与JSON格式的双向转换,适配Firestore和本地测试JSON的结构:

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

class GeoPointConverter implements JsonConverter<GeoPoint, Map<String, dynamic>> {
  const GeoPointConverter();

  @override
  GeoPoint fromJson(Map<String, dynamic> json) {
    return GeoPoint(
      (json['latitude'] as num).toDouble(),
      (json['longitude'] as num).toDouble(),
    );
  }

  @override
  Map<String, dynamic> toJson(GeoPoint object) {
    return {
      'latitude': object.latitude,
      'longitude': object.longitude,
    };
  }
}

2. 在Freezed类中应用转换器

修改你的Place类,通过@JsonSerializable注解全局应用转换器,确保Freezed生成的代码能正确处理GeoPoint类型:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'place.freezed.dart';
part 'place.g.dart';

@Freezed()
@JsonSerializable(converters: [GeoPointConverter()])
class Place with _$Place {
  const factory Place({
    required String id,
    required String name,
    required GeoPoint location,
  }) = _Place;

  factory Place.fromJson(Map<String, dynamic> json) => _$PlaceFromJson(json);
}

如果只需要给location字段单独配置转换器,也可以直接在字段上标注:

const factory Place({
  required String id,
  required String name,
  @GeoPointConverter() required GeoPoint location,
}) = _Place;

3. 验证测试JSON结构

确保places.json中的location字段格式与转换器匹配,示例结构:

[
  {
    "id": "1",
    "name": "测试地点",
    "location": {
      "latitude": 31.2304,
      "longitude": 121.4737
    }
  }
]

4. 重新执行构建命令

清理旧的生成文件并重新构建,避免缓存冲突:

flutter pub run build_runner build --delete-conflicting-outputs

关键说明

之前尝试的@JsonKey自定义方法容易和Freezed的代码生成逻辑冲突,而JsonConverter是更适配Freezed+json_serializable组合的方案——它会被Freezed识别并自动注入到序列化/反序列化流程中,同时兼容Firestore的GeoPoint存储格式:

  • 写入Firestore时,直接将Place对象传入setData,Firestore会自动识别GeoPoint类型
  • 读取Firestore数据时,用Place.fromJson(doc.data()!)即可完成反序列化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 20:07:12