1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Jetpack Compose で Firestore のサブスクリプションを利用する

Last updated at Posted at 2021-09-19

はじめに

Jetpack Compose には React のフックに似た仕組みがあり、その仕組みを利用することで Firestore のサブスクリプション周りの雑多な処理を関数として抜き出すことができます。

実装

次のコードは、messages コレクションに何らかの変化があったときにメッセージのリストを再生成する関数です。

data class Message(
  @DocumentId val id: String = "",
  val sender: String = "",
  val receiver: String = "",
  val content: String = "",
)

@Composable
fun rememberMessages(): List<Message> {
  val messages = remember { mutableStateListOf<Message>() }

  DisposableEffect(Unit) {
    val registration = Firebase.firestore
      .collection("messages")
      .addSnapshotListener { snapshot, e ->
        if (e != null || snapshot == null) {
          Log.e("ERROR", "listen:error", e)
          return@addSnapshotListener
        }
        for (dc in snapshot.documentChanges) {
          val doc = dc.document.toObject(Message::class.java)
          when (dc.type) {
            DocumentChange.Type.ADDED -> {
              messages.add(doc)
            }
            DocumentChange.Type.MODIFIED -> {
              val index = messages.indexOfFirst { it.id == doc.id }
              messages[index] = doc
            }
            DocumentChange.Type.REMOVED -> {
              messages.removeIf { it.id == doc.id }
            }
          }
        }
      }
    onDispose {
      registration.remove()
    }
  }

  return messages.toList()
}

mutableStateListOf を使うことで、ミュータブルかつ変更の検知可能なリストを作ることができます。このリストの要素を追加、修正、削除したときは再コンポーズが走ります。

addSnapshotListener により、messages コレクションの変更内容を知ることができます。もし既に messages コレクションに10個のドキュメントが存在するとき、ハンドラを登録したタイミングで dc.type == DocumentChange.Type.ADDED のブロックが10回呼ばれます。よって、たったこれだけのコードでドキュメント一覧の取得とサブスクリプションが完了しています。

呼び出し側では次のように書くだけです。

@Composable
fun MyScreen() {
  val messages = rememberMessages()
}

messages コレクションに何らかの変更が行われたときに MyScreen の再コンポーズが走ります。

おわりに

まさか、ここまできれいに Firestore のサブスクリプション部分を関数として切り出せるとは思いませんでした。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?