📝
Firestoreに書き込み後FieldValueがnullになる問題
Problem
FieldValue.serverTimestamp()を使ってcreatedAtやupdatedAtがあるdoc(下記のデータみたいなの)をFirestoreに書き込んだらlisten中のstreamに書き込んだデータが戻ってきたが createdAtとupdatedAtがnullになっている
final data = <String, dynamic>{
value: 'Hello'
createdAt: FieldValue.serverTimestamp();
updatedAt: FieldValue.serverTimestamp();
}
もしcreatedAtとupdatedAtがOptionalの場合は問題がないが、普段は必須項目のためassertでnullチェックしているとエラーが出る。
Solution
Firestoreの書き込み途中でサーバー側のFieldValue.serverTimestamp()がまだ解決されていないため、null が戻っている。本来だったら SnapshotOptions の estimateをget()や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);
Discussion