FirebaseでPubSubしてみる(Cloud Firestore)
背景
- なんとなく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)
}
}
なんて簡単なんや。。
FireStoreのデータを監視する。
これも簡単。
- 対象のCollectionのQueryを取得する。
- EventListener<QuerySnapshot>をimplement、onEventを実装する。
- 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実装できるので、チャット等は簡単に作れそう。