背景

  • なんとなくFirebase使ったことないのまずいかなぁと思ってFirebaseに手を出してみる。
  • 今まではPush通知くらいしか使ってなかった。
  • 今回はCloud Firestoreを利用してPub / Subの仕組みを作ってみる

Cloud Firestore

NoSQLドキュメント指向データベースらしい。

[https://firebase.google.com/docs/firestore/data-model?hl=ja:embed:cite]

ちなみに NoSQLっていうのはNot Only SQLの略で、SQL言語を利用しないDBのこと。Realmとかそうですね。
ドキュメント指向というのはSQLにおけるテーブルとかカラムみたいな管理ではなく、自由なデータ構造を持つドキュメントを一つの単位として持ちます。
そのためSQLと違い事前にデータ構造を決めておく必要がないみたいですね。すごい。

サンプルを組んでみる

codeLabあった!やった!

[https://codelabs.developers.google.com/codelabs/firestore-android/#0:embed:cite]

build.gradleに依存関係を追加

    // Firestore
    implementation 'com.google.firebase:firebase-firestore:17.1.5'

とりあえずcollectionに追加してみる。

FireBaseFireStoreのインスタンスを取得して、対象のcollectionにaddするだけ。簡単。

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // FireBaseFireStore: すべてのFireBaseデータベースのエントリポイント。
        val firebase = FirebaseFirestore.getInstance()

        // コレクションに追加するオブジェクト(ドキュメント)
        val user = User("testiD")

        // collection:users にuserオブジェクト(ドキュメント)を追加
        firebase.collection("users").add(user)

    }
}

image

なんて簡単なんや。。

FireStoreのデータを監視する。

これも簡単。

  1. 対象のCollectionのQueryを取得する。
  2. EventListener<QuerySnapshot>をimplement、onEventを実装する。
  3. QueryにaddSnapshotListenerを設定する。

とりあえず適当にActivityに書いてみる。
(めんどくさかったのでfindViewByIdを使いましたが、実際はKotlin Android ExtensionsかDataBinding使った方がいいです)


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // FireBaseFireStore: すべてのFireBaseデータベースのエントリポイント。
        val firebase = FirebaseFirestore.getInstance()
        findViewById<Button>(R.id.button).setOnClickListener {
            // コレクションに追加するオブジェクト(ドキュメント)
            val user = User("testiDBbcb")

            // collection:users にuserオブジェクト(ドキュメント)を追加
            firebase.collection("testUsers").add(user)
        }

        // Queryを作成する。collectionはcollectionReferenceを返しているんだけど、
        // collectionReferenceはQueryを継承しているクラスなので、Queryのメソッドが利用できる。
        val query = firebase.collection("testUsers")

        // Snapshotのリスナーを設定する。
        query.addSnapshotListener(this)

    }

    override fun onEvent(querySnapshot: QuerySnapshot?, firebaseFirestoreExeption: FirebaseFirestoreException?) {

        // nullableなので念の為。
        if (querySnapshot == null) {
            return
        }

        querySnapshot.documentChanges
                .forEach {
                    // typeは3つ。追加か変更か削除
                    when (it.type) {
                        DocumentChange.Type.ADDED -> {
                            val data = it.document.data
                            findViewById<TextView>(R.id.textView).text = data["userId"].toString().plus(" ADDED")
                        }
                        DocumentChange.Type.MODIFIED -> {
                            val data = it.document.data
                            findViewById<TextView>(R.id.textView).text = data["userId"].toString().plus(" MODIFERD")
                        }
                        DocumentChange.Type.REMOVED -> {
                            findViewById<TextView>(R.id.textView).text = "Remove"
                        }
                        else -> {
                            findViewById<TextView>(R.id.textView).text = "else"
                        }
                    }
                }
    }
}

これでPub / Sub的な実装が完成した。

感想

  • そこらへんのBaasよりすごい使いやすかった。
  • 簡単にPub / Sub実装できるので、チャット等は簡単に作れそう。