Jetpack ComposeでFirestoreからデータを取得する方法
対象者:
- すでに Firebase と Android の接続が完了している方
公式の手順通りに進めれば終わるはずです!!
- ViewModelの知識が少しある方
Firestore にデータを入れる
まずは取得するためのデータを作っていきます。
Firebase のデータベース作成を選択したら、以下のような画面が出てくるので、データベース ID を入れて、「次へ」を押します。
(私は ID を「test」にしました。)
次にルールを設定します。セキュリティみたいなものですね。
今回動かすのはサンプルなので、テストモードにしておきます。
データベースが作成されます。
左側の「コレクションを追加」を押します。
コレクションは、テーブル的なものです。
今回は、ユーザーデータを作成していきます。
なので、名前は「users」にします。
コレクションができたら、データを入れていきましょう。
ドキュメントが1つのレコード(1 行分のデータ)になります。
今回は、name と age 属性を与えます。
ドキュメント ID は自動生成で大丈夫です。
3 つデータを入れてみました。
Jetpack ComposeFirestore からデータを取得する方法
まずは、gradle の設定からです。
build.gradle.kts(Module:App)
dependencies {
// ...
// Firestore
implementation("com.google.firebase:firebase-firestore")
// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
}
ui ディレクトリに新しく「TestViewModel.kt」ファイルを作成します。
TestViewModel.kt
class TestViewModel {
}
状態変数を設定します。
TestViewModel.kt
class TestViewModel : ViewModel() {
private val _uiState = MutableStateFlow(listOf<User>())
val uiState: StateFlow<List<User>> = _uiState.asStateFlow()
}
クラスの中に、データ取得のための関数を書いていきます。
TestViewModel.kt
// データ取得
private fun fetchUserData() {
val db = Firebase.firestore
db.collection("users")
.get()
.addOnSuccessListener { result ->
for (document in result) {
Log.d("SUCCESS", "${document.id} => ${document.data}")
}
}
.addOnFailureListener { exception ->
Log.w("FAILED", "Error getting documents.", exception)
}
}
インスタンス化した時に動いて欲しいので、初期化処理の中に、先ほど書いた関数を入れます。
TestViewModel.kt
class testViewModel : ViewModel() {
private val _uiState = MutableStateFlow(listOf<User>())
val uiState: StateFlow<List<User>> = _uiState.asStateFlow()
// 初期化
init {
fetchUserData()
}
MainActivity の方に戻って、さきほどのクラスをインスタンス化してみて、ちゃんとデータが取得できるかみてみましょう。
MainActivity.kt
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
val testViewModel: TestViewModel = viewModel()
// ...
}
エミュレータを起動して実行します・・・
ちゃんと動いていそうですね!!
次に、これらのデータを、UI に表示できる形にしたいです。
なので、まずは User のデータ型を宣言してあげます。
TestViewModel.kt
data class User(
val id: String,
val name: String,
val age: Int?
)
class TestViewModel : ViewModel() {
// ...
つぎに、fetchUserData 関数で、データが取得できた時の処理を変更します。
TestViewModel.kt
private fun fetchUserData() {
// 取得したデータをまとめるためのリスト
val users = mutableListOf<User>()
val db = Firebase.firestore
db.collection("users")
.get()
.addOnSuccessListener { result ->
for (document in result) {
// ユーザーデータ取得
val userData = User(
id = document.id,
name = document.data["name"].toString(),
age = document.data["age"].toString().toInt(),
)
// 配列に代入
users.add(userData)
}
// 状態を更新
_uiState.update {
users
}
}
.addOnFailureListener { exception ->
Log.w("FAILED", "Error getting documents.", exception)
}
}
↑age のところ「.toString().toInt()」になっていて気持ち悪いです。。。
実力不足ですみません。。。
状態が更新されるようになったので、UI の方も変えていきましょう。
MainActivity.kt
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
val testViewModel: TestViewModel = viewModel()
val users by testViewModel.uiState.collectAsState()
LazyColumn {
item {
users.map { user ->
Row {
Text(text = user.name)
Text(text = user.age.toString())
}
}
}
}
}
これで表示されるはずです!
実行してみましょう。
表示できました!!やったー!!!🙌
参考
🙂↕️最後まで読んでいただきありがとうございます🙂↕️