Firebase Cloud Firestore + RxJava / RxKotlin のオブジェクト変換
はじめに
Firebase の Cloud Firestore で
DocumentSnapshot または QuerySnapshot から モデルに変換する方法を紹介します。
解決策
Firestoreが用意してくれている toObject 関数を使えば終わりです。
FirebaseFirestore.getInstance() .collection("users") .get() .addOnSuccessListener { val cars = it.toObjects(User::class.java) }
使いやすく改良
RxJava / RxKotlin を使用していればもうしこし使いやすくしてみましょう!
そのためには、前回のこの記事も読んでみてください。
qoopmk.hatenablog.jp
ちなみに、toObject に渡している ESTIMATEについてはこちらで説明しています!
qoopmk.hatenablog.jp
/** * QuerySnapshotをモデルに変換 * * @return QuerySnapshot */ @CheckResult inline fun <reified T> Single<QuerySnapshot>.toObjects(): Single<List<T>> { return map { it.toObjects(T::class.java, DocumentSnapshot.ServerTimestampBehavior.ESTIMATE) } } /** * DocumentSnapshotをモデルに変換 * * @return DocumentSnapshot */ @CheckResult inline fun <reified T> Single<DocumentSnapshot>.toObject(): Single<T> { return map { it.toObject(T::class.java, DocumentSnapshot.ServerTimestampBehavior.ESTIMATE) } }
結果
このように Firestore のリクエストがすごく簡単になります。
fun findAll(): Single<List<User>> { return FirebaseFirestore.getInstance() .collection("users") .get() .toSingle() .toObjects() } fun findById(id: String): Single<User> { return FirebaseFirestore.getInstance() .collection("users") .document(id) .get() .toSingle() .toObject() }
注意すべきこと
FirestoreではKotlin data class に変換する際は注意が必要です。
引数のないのコンストラクタがないとエラーになって変換できないので、toObject で指定するdata class にはデフォルト値を入れるか空のコンストラクタを用意しておきましょう!
data class User( val id : String = "", val name : String = "", val age : Int? = null, )