ログイン機能やNoSQLでデータベースを提供してくれるFirestoreですが、RecyclerViewにデータを表示するときに詰まりました。日本語の記事が少なかったので備忘録として記していきます。
#今日のゴール
苗字と名前を入力し、ボタンを押したらFirestoreに保存。そのままリサイクラービューに表示できたらOK
「名前」「姓」の順番なのは僕がイギリス人だからです。嘘です。
##下ごしらえ
Firestoreのデータベースの作成がまだの方は以下のページを参考に作成。
Cloud Firestore を使ってみる
次にボタンをクリックしたら保存できるようにする。
add_button.setOnClickListener {
val firstName = firstname_edit.text.toString()
val lastName = lastname_edit.text.toString()
val user = User(firstName, lastName)
// ドキュメントのIDは自動生成されます。
db.collection("users")
.add(user)
.addOnSuccessListener { documentReference ->
Log.d(TAG, "DocumentSnapshot added with ID: ${documentReference.id}")
}
.addOnFailureListener { e ->
Log.w(TAG, "Error adding document", e)
}
}
Cloud Firestore にデータを追加する
Firestoreのデータベース画面に保存が反映されていたら次に進みます。
##Firebase UIをインポート
// FirebaseUI for Cloud Firestore
implementation 'com.firebaseui:firebase-ui-firestore:6.2.1'
FirebaseUIはFirestoreから取ってきたデータでオブジェクトを作成し、リサイクラービュー に受け渡すところまでやってくれるようになるイメージです。
2種類のアダプターが用意されています。
・FirestoreRecyclerAdapter
→項目の追加、削除、移動、といった変更をリアルタイムに反映。
・FirestorePagingAdapter
→ページの読み込みのたびに更新。(=データ変更時の即時更新ではない)大規模なデータセットでの使用に最適
今回はFirestoreRecyclerAdapterを使用します。
この後やることは
1. Firestoreからデータを取ってくる
2. ViewHolderの作成
3. FirestoreRecyclerAdapterを継承したアダプターを作成
4. 変更を読み取るリスナーの設置
##Firestoreからデータを取ってくる
val db = FirebaseFirestore.getInstance()
val query = db.collection("users").orderBy("firstName", Query.Direction.ASCENDING)
//Firebase UI を入れる事で使用可能に
val options = FirestoreRecyclerOptions.Builder<User>().setQuery(query, User::class.java).build()
Firestoreのデータベースを作成し、取得したデータをqueryに代入
##ViewHolderの作成
今回は参考にしたサイト通りにMainActivityに書きました。
private inner class UserViewHolder internal constructor(private val view: View) : RecyclerView.ViewHolder(view){
internal fun setUserName(firstName: String, lastName: String){
val textviewFirst = view.findViewById<TextView>(R.id.text_first)
textviewFirst.text = firstName
val textviewLast = view.findViewById<TextView>(R.id.text_last)
textviewLast.text = lastName
}
}
##FirestoreRecyclerAdapterを継承したアダプターを作成
リサイクラービューアダプターとほとんど一緒かなと思います。
getItemCount()がなくていいのかなと迷いました、、
詳しい方教えていただけたら嬉しいです(.. )
private inner class UserFirestoreRecyclerAdapter internal constructor(options: FirestoreRecyclerOptions<User>):FirestoreRecyclerAdapter<User, UserViewHolder>(options){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item,parent, false)
return UserViewHolder(view)
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int, model: User) {
holder.setUserName(model.firstName!!, model.lastName!!)
}
}
##変更を読み取るリスナーの設置
これが大事らしいですよ。忘れずに。
override fun onStart() {
super.onStart()
adapter!!.startListening()
}
override fun onStop() {
super.onStop()
if(adapter != null){
adapter!!.stopListening()
}
}
###感想
とりあえず表示するだけならこれでいけるかと思います。
間違いやコードのミスなどありましたらご指摘ください。
####参考
Display data from Firebase Firestore to RecyclerView with KOTLIN [closed]
Android向けFirebaseUI-FirebaseのUIバインディング
FirebaseUI-Android