Closed ywake closed 4 months ago
I solve this with a custom converter:
/// Use with @JsonKey(toJson: replaceWithServerTimestamp)
dynamic replaceWithServerTimestamp(DateTime dateTime) => FieldValue.serverTimestamp();
/// When setting FieldValue.serverTimestamp(), a listener might receive a null value
DateTime useNowIfNull(dynamic value) => value == null ? DateTime.now() : const FirestoreDateTimeConverter().fromJson(value as Timestamp);
class ServerTimestamp extends JsonKey {
const ServerTimestamp() : super(toJson: replaceWithServerTimestamp, fromJson: useNowIfNull);
}
Usage:
@firestoreSerializable
class _Identification {
Task({
required this.title,
this.createdAt = DateTime.now(),
});
final String title;
@ServerTimestamp()
final DateTime createdAt;
}
@gmarizy
Thanks! Looks very good!
In that code, the generator applied FirestoreDateTimeConverter
incorrectly, so I modified it.
class ServerTimestamp extends JsonConverter<DateTime, dynamic> {
const ServerTimestamp();
@override
DateTime fromJson(dynamic json) => json == null
? DateTime.now()
: const FirestoreDateTimeConverter().fromJson(json as Timestamp);
@override
dynamic toJson(DateTime object) => FieldValue.serverTimestamp();
}
[!WARNING] Please note that using
.set()
will update thecreatedAt
field to the current time. You will need to implement a condition to decide whether or not to update this field, as shown in the example below. ( Using.update()
does not have this issue. )
@override
dynamic toJson(DateTime? object) => object == null
? FieldValue.serverTimestamp()
: const FirestoreDateTimeConverter().toJson(object);
I'm currently adding with a temporary value and then updating. Is there a better way?