json - 如何在 Firebase(Flutter/dart)中添加具有 DocumentReference 类型的对象?
问题描述
我想在 firebase 的帖子文档中引用一个类别文档。这是我的数据类,我也在使用 freezed 和 json_serializer:
部分“post_dto.freezed.dart”; 部分'post_dto.g.dart'; 部分'category_dto.freezed.dart'; 部分'category_dto.g.dart'; @冻结 带有 _$PostDTO { 的抽象类 PostDTO 常量 PostDTO._(); 常量工厂 PostDTO({ @JsonKey(忽略:真)字符串?ID, 必需的字符串标题, 必需的字符串描述, @DocumentReferenceConveter() 文档参考?类别参考, }) = _PostDTO; 工厂 PostDTO.fromJson(Map json) => _$PostDTOFromJson(json); 工厂 PostDTO.fromFireStore(DocumentSnapshot 文档) { 地图数据 = document.data() as Map; return PostDTO.fromJson(data).copyWith(id: document.id); } } @冻结 抽象类 CategoryDTO 与 _$CategoryDTO { 常量类别DTO._(); 常量工厂 CategoryDTO({ 必需的字符串图标, 必需的字符串名称, }) = _CategoryDTO; 工厂 CategoryDTO.fromFireStore(DocumentSnapshot 文档) { 地图数据 = document.data() as Map; 返回 CategoryDTO.fromJson(data); } 工厂 CategoryDTO.fromJson(Map json) => _$CategoryDTOFromJson(json); }
当我运行 build_runner 时,我得到了这个错误:
[严重] json_serializable:lib/infrastructure/post/post_dto.dart 上的 json_serializable: 无法为“categoryReference”生成“fromJson”代码。 要支持“DocumentReference”类型,您可以: * 使用`JsonConverter` https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html * 使用 `JsonKey` 字段 `fromJson` 和 `toJson` https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html 包:UPLFY/infrastructure/post/post_dto.freezed.dart:373:41 ╷ 373│最终的DocumentReference?类别参考; │ ^^^^^^^^^^^^^^^^^ ╵ [INFO] 运行构建完成,耗时 2.5 秒 [INFO] 正在缓存最终的依赖关系图... [INFO] 缓存最终依赖图完成,耗时 44 毫秒 [严重] 2.5 秒后失败
所以尝试使用 JsonConverter 但我不确定如何将 json 对象转换为 DocumentReference ...
类 DocumentReferenceConveter 实现 JsonConverter,对象> { 常量 DocumentReferenceConveter(); @覆盖 DocumentReference fromJson(Object json) { return //TODO: 将 json 转换为 DocumentReference } @覆盖 对象 toJson(DocumentReference documentReference) => 文件参考; }
解决方案
我能够从我在网上找到的研究中总结出我的解决方案,并且到目前为止想出了这个。
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:json_annotation/json_annotation.dart';
class DocumentReferenceJsonConverter
implements JsonConverter<DocumentReference?, Object?> {
const DocumentReferenceJsonConverter();
@override
DocumentReference? fromJson(Object? json) {
return tryCast<DocumentReference>(json);
}
@override
Object? toJson(DocumentReference? documentReference) => documentReference;
}
T? tryCast<T>(value) {
return value == null ? null : value as T;
}
...
import 'package:freezed_annotation/freezed_annotation.dart';
part 'user_profile.freezed.dart';
part 'user_profile.g.dart';
@freezed
class UserProfile with _$UserProfile {
const UserProfile._();
@TimestampConverter()
@DocumentReferenceJsonConverter()
@JsonSerializable(
explicitToJson: true,
fieldRename: FieldRename.snake,
includeIfNull: false,
)
factory UserProfile({
@JsonKey(ignore: true) DocumentReference? reference,
String? avatarUrl,
required String email,
required String firstName,
required String lastName,
Gender? gender,
DateTime? birthday,
String? additionalInfo,
Contact? contact,
DocumentReference? familyReference,
DateTime? createdAt,
}) = _UserProfile;
factory UserProfile.empty() => UserProfile(email: '', firstName: '', lastName: '');
factory UserProfile.fromJson(Map<String, dynamic> json) => _$UserProfileFromJson(json);
factory UserProfile.fromDocument(DocumentSnapshot documentSnapshot) {
final data = documentSnapshot.data();
return data != null
? UserProfile.fromJson(data as Map<String, dynamic>)
.copyWith(reference: documentSnapshot.reference)
: UserProfile.empty();
}
推荐阅读
- android - 找不到附近的地方
- reactjs - iOS 和 Android 是否支持带有 react native 的动画 GIF 图像?
- scikit-learn - sklearn.linear_model.Lasso中参数“选择”的作用是什么
- ios - 如何将 tableview 单元格附件应用于 tableview 记录
- https - 使用 GOST 2012 (ГОСТ Р 34.10-2012) 和 Python 2.7.15+ 的 https 连接:
- c# - 指定的演员在 Acumatica ERP 系统的新主屏幕中无效
- c++ - C++ 添加检查以避免读取两个参数
- c# - 如何将 Automapper 与 Autofac 一起使用
- oracle - 如何使用 get_ddl 获取分区脚本?
- r - R 等效于 SAS EG 工艺流程