🕑
Cloud Firestore ODMでサーバータイムスタンプを使う方法
Github |
---|
cloud_firestore_odm: ^1.0.0-dev.84
で確認
実現したいこと
FlutterのCloud Firestore ODMでFirestoreを操作する際、createdAt
やupdatedAt
などのフィールドにサーバータイムスタンプを使いたい。
ODMを使わないならFieldValue.serverTimestamp()
を直接使えばいいが、ODMにはそれらしいものがなかった。
解決方法
カスタムコンバーターを作成して、toJson()
の際にFieldValue.serverTimestamp()
に変換する。
class ServerTimestamp extends JsonConverter<DateTime, dynamic> {
const ServerTimestamp();
DateTime fromJson(dynamic json) => json == null
? DateTime.now()
: const FirestoreDateTimeConverter().fromJson(json as Timestamp);
// サーバータイムスタンプをセットする際に、リスナーが一瞬nullを受信することがある
// のでその瞬間はクライアントの現在時間を使用
dynamic toJson(DateTime object) => FieldValue.serverTimestamp();
}
使い方
class Task {
Task({
this.id,
required this.title,
required this.createdAt,
required this.updatedAt,
});
()
final String? id;
final String title;
()
final DateTime createdAt;
()
final DateTime updatedAt;
}
注意
.update()
を使う際には問題ないが、.set()
を使う際にはcreatedAt
も更新されてしまうので注意が必要。
.set()
にも対応するなら以下のようにして更新するときだけnull
を渡すなどの工夫が必要。
class ServerTimestamp extends JsonConverter<DateTime?, dynamic> {
const ServerTimestamp();
DateTime? fromJson(dynamic json) => json == null
? DateTime.now()
: const FirestoreDateTimeConverter().fromJson(json as Timestamp);
dynamic toJson(DateTime? object) => object == null
? FieldValue.serverTimestamp()
: const FirestoreDateTimeConverter().toJson(object);
}
class Task {
Task({
this.id,
required this.title,
this.createdAt,
this.updatedAt,
});
()
final String? id;
final String title;
()
final DateTime? createdAt;
()
final DateTime? updatedAt;
}
参考
合わせて読みたい
Discussion