Cloud Firestore で ServerTimestamp が null になる問題
AndroidでCloud Firestoreを使っていて、
データをCollectionに追加する際に、ServerTimestampを使って日時を設定していました。
以下のようなコードでもFirestoreには問題なく作成日時(createdAt)は保存されます。
/** * メッセージ * * @property id メッセージID * @property content メッセージの内容 */ data class Message( val id: String, val content: String ) { @ServerTimestamp val createdAt: Date? = null }
しかし、これと同時に購読処理を行なっている場合は注意が必要です。
例えば、チャット画面などで購読処理 & 送信(Collection追加) が同時に行われるケース。
FirebaseFirestore.getInstance() .collection("messages") .addSnapshotListener(MetadataChanges.INCLUDE) { snapshot, exception -> // 購読処理 // ... val messages = snapshot.toObjects(Message::class.java) }
あれ、購読処理でうけとった createdAt が null になるぞ、、
これでだいぶハマりましたが、どうやらFirestoreの仕様のようです。
理想:Collection追加→ServerTimestampでcreatedAtを設定→購読処理
現実:Collection追加→購読処理→ServerTimestampでcreatedAtを設定
となるようです。
解決策として、toObject() の第二引数に、ServerTimestampの振る舞いを設定してあげてください。
今回は、ESTIMATE(おおよその時間)を設定しました。
FirebaseFirestore.getInstance() .collection("messages") .addSnapshotListener(MetadataChanges.INCLUDE) { snapshot, exception -> // 購読処理 // ... val messages = snapshot.toObjects(Message::class.java, DocumentSnapshot.ServerTimestampBehavior.ESTIMATE) }
こうすることで、 createdAt は null ではなくなります^^