Firestoreからデータを取得してRecyclerViewに表示［Kotlin］

ログイン機能やNoSQLでデータベースを提供してくれるFirestoreですが、RecyclerViewにデータを表示するときに詰まりました。日本語の記事が少なかったので備忘録として記していきます。

#今日のゴール
苗字と名前を入力し、ボタンを押したらFirestoreに保存。そのままリサイクラービューに表示できたらOK
「名前」「姓」の順番なのは僕がイギリス人だからです。嘘です。
<img width="200" alt="Screenshot_1588942724.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611160/845032c5-ecb7-61c2-35fe-a851bb018269.png">
##下ごしらえ
Firestoreのデータベースの作成がまだの方は以下のページを参考に作成。
[Cloud Firestore を使ってみる](https://firebase.google.com/docs/firestore/quickstart?hl=ja)
次にボタンをクリックしたら保存できるようにする。

```MainActivity.kt
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 にデータを追加する](https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja)
Firestoreのデータベース画面に保存が反映されていたら次に進みます。

##Firebase UIをインポート
```app/build.gradle
   // FirebaseUI for Cloud Firestore
    implementation 'com.firebaseui:firebase-ui-firestore:6.2.1'
```

FirebaseUIはFirestoreから取ってきたデータでオブジェクトを作成し、リサイクラービュー に受け渡すところまでやってくれるようになるイメージです。
２種類のアダプターが用意されています。

**・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に書きました。

```MainActivity.kt
    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]
](https://stackoverflow.com/questions/51746587/display-data-from-firebase-firestore-to-recyclerview-with-kotlin)[Android向けFirebaseUI-FirebaseのUIバインディング](https://firebaseopensource.com/projects/firebase/firebaseui-android)
[FirebaseUI-Android](https://github.com/firebase/FirebaseUI-Android/tree/master/firestore)