Ree*_*eed 10 dart flutter google-cloud-firestore
我想从 Firestore 获取会议并将它们映射到以下Meeting模型中:
part 'meeting.g.dart';
@JsonSerializable(explicitToJson: true)
class Meeting {
String id;
DateTime date;
Meeting(this.id, this.date);
factory Meeting.fromJson(Map<String, dynamic> json) {
return _$MeetingFromJson(json);
}
Map<String, dynamic> toJson() => _$MeetingToJson(this);
}
Run Code Online (Sandbox Code Playgroud)
文档是从 Firestore 获取的,然后fromJson在可迭代对象上调用,但会引发异常:
type 'Timestamp' is not a subtype of type 'String' in type cast
Run Code Online (Sandbox Code Playgroud)
当我进入 generate 时meeting.g.dart,正是这一行导致了错误
json['date'] == null ? null : DateTime.parse(json['date'] as String)
Run Code Online (Sandbox Code Playgroud)
为了解决此问题,我尝试将模型中的 DateTime 更改为 Timestamp,但随后显示以下构建错误:
Error running JsonSerializableGenerator
Could not generate `fromJson` code for `date`.
None of the provided `TypeHelper` instances support the defined type.
Run Code Online (Sandbox Code Playgroud)
你能告诉我你是如何解决这个问题的吗?是否有另一种首选方法将 Firebase 和 Flutter 项目结合使用 json_serializable 进行 JSON 序列化?甚至可以替换 json_serializable 的使用?
Jun*_*Lee 13
class TimestampConverter implements JsonConverter<DateTime, Timestamp> {
const TimestampConverter();
@override
DateTime fromJson(Timestamp timestamp) {
return timestamp.toDate();
}
@override
Timestamp toJson(DateTime date) => Timestamp.fromDate(date);
}
@JsonSerializable()
class User{
final String id;
@TimestampConverter()
final DateTime timeCreated;
User([this.id, this.timeCreated]);
factory User.fromSnapshot(DocumentSnapshot documentSnapshot) =>
_$UserFromJson(
documentSnapshot.data..["_id"] = documentSnapshot.documentID);
Map<String, dynamic> toJson() => _$UserToJson(this)..remove("_id");
}
Run Code Online (Sandbox Code Playgroud)
使用toJson和fromJson转换器函数如下例所示: https: //github.com/dart-lang/json_serialized/blob/master/example/lib/example.dart
该解决方案的好处是您不必对属性名称进行硬编码
阅读https://github.com/dart-lang/json_serialized/issues/351后,我已经更改Meeting.fromJson并且现在按预期工作:
factory Meeting.fromJson(Map<String, dynamic> json) {
json["date"] = ((json["date"] as Timestamp).toDate().toString());
return _$MeetingFromJson(json);
}
Run Code Online (Sandbox Code Playgroud)
json["date"]默认情况Timestamp下,我String在它到达生成的反序列化器之前将其转换为 , ,因此当它尝试强制转换时不会崩溃json["date"] as String
不过,我不太喜欢这种解决方法,因为我必须对属性的名称和类型进行硬编码,但就目前而言,这个解决方案已经足够好了。
另一种方法是尝试使用https://pub.dev/packages/built_value进行序列化,这是他们的博客中推荐的https://flutter.dev/docs/development/data-and-backend/json
感谢@Reed 指出正确的方向。将DateTimevalue传递给FireStorefirebase 时,似乎没有问题将该值作为Timestamp,但是在取回它时需要正确处理。无论如何,这里有一个例子,它是双向的:
import 'package:cloud_firestore/cloud_firestore.dart'; //<-- dependency referencing Timestamp
import 'package:json_annotation/json_annotation.dart';
part 'test_date.g.dart';
@JsonSerializable(anyMap: true)
class TestDate {
@JsonKey(fromJson: _dateTimeFromTimestamp, toJson: _dateTimeAsIs)
final DateTime theDate;
TestDate({this.theDate,});
factory TestDate.fromJson(Map<String, dynamic> json) {
return _$TestDateFromJson(json);
}
Map<String, dynamic> toJson() => _$TestDateToJson(this);
static DateTime _dateTimeAsIs(DateTime dateTime) => dateTime; //<-- pass through no need for generated code to perform any formatting
// /sf/ask/3963952191/
static DateTime _dateTimeFromTimestamp(Timestamp timestamp) {
return DateTime.parse(timestamp.toDate().toString());
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3214 次 |
| 最近记录: |