🕑
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