Firestoreに書き込み後FieldValueがnullになる問題

1 min読了の目安(約1300字TECH技術記事

Problem

FieldValue.serverTimestamp()を使ってcreatedAtupdatedAtがあるdoc(下記のデータみたいなの)をFirestoreに書き込んだらlisten中のstreamに書き込んだデータが戻ってきたが createdAtupdatedAtnullになっている

final data = <String, dynamic>{
  value: 'Hello'
  createdAt: FieldValue.serverTimestamp();
  updatedAt: FieldValue.serverTimestamp();
}

もしcreatedAtupdatedAtOptionalの場合は問題がないが、普段は必須項目のためassertnullチェックしているとエラーが出る。

Solution

Firestoreの書き込み途中でサーバー側のFieldValue.serverTimestamp()がまだ解決されていないため、null が戻っている。本来だったら SnapshotOptionsestimateget()data()をオブションとして渡したらサーバーが解決中でクライアント側の時間が戻ってくるが、当時にはFlutterのライブラリーにはSnapshotOptionsがまだ実装されていない(?)のでそれがまだ使えないためDocumentSnapshotまたはQuerySnapshotのmetadataを見て書き込み途中かどうかを判断してsinkをデータに追加するようにする。

final stream = _fireStore.collection('collectionA').doc(docId).snapshots();
final transformer =
    StreamTransformer<DocumentSnapshot, MyData>.fromHandlers(
  handleData: (snapshot, sink) {
    if (!snapshot.metadata.hasPendingWrites) {
      final data = snapshot.data();
      final session = Session.fromJson(data);
      sink.add(session);
    }
  },
  handleError: (error, trace, sink) {
    sink.addError(error, trace);
  },
);

return stream.transform(transformer);