Honmushi blog
2019/07/31

スマホアプリ開発でFirestoreを使ってみる

最近React NativeとExpoを利用してスマホアプリを作っています。 いくつかAndroidで公開もしているので興味があればこちらからどうぞ

そのなかでもいくつかのアプリについてはFirebaseをバックエンドとして利用しました。 Firebaseは認証やDB、ストレージなどを提供するWebアプリケーション開発プラットフォームというようなGoogleのサービスです。

今回はその中でも「Firestore」というデータベースを使った感想を記録します。

概要

  • サーバレスという概念
  • Authとの連携
  • NoSQL型
  • クエリによるデータの取得

サーバレスという概念

よく考えたらややこしいのですが。Firebaseを使う場合でもAPIを用意したり、DBとしてデータを保持します。

それってサーバじゃない?と思いますが、大きく違うのはサーバの管理が不要ということです。 サーバがちゃんと動いているかとかサービス立ち上げるとかがほぼ不要で、簡単に始めることができ管理も簡単です。 アプリから直接DBサーバに同期するここもでき、使いどころに注意が必要ですが簡単に難しい機能を実現できます。

最初にアプリケーションを設定が必要だったり、必要な機能を有効にしたりする必要はありますが、ブラウザから設定できます。 APIなどのソースコードをデプロイするのもとても簡単です。できることは制限されますが、その分簡単に利用できます。 ログなんかもブラウザで確認出来ます。DBもです。

バックエンドの経験もある私の使用感としては、サーバ管理のコストが大幅に減ることが大きく実感しました。

Authとの連携

Firestoreにはセキュリティルールをもうけることが出来ます。誰でもデータの読み取り・書き込みできては困るので、通常制御すると思います。

Firebase のAuthenticationと組み合わせて使うことで、「ログインしている場合のみデータへのアクセス可能」と言ったセキュリティルールを実現できます。Functions経由の場合はログインは不要でした。この使い方も便利そうでした。

NoSQL型

FirestoreはNoSQLと呼ばれるDBを採用しており、RDBとは大きく違います。RDBで当たり前のようにやっていたことができなかったりしますが、そもそもの仕組みが違うため概念から改めて考え直す必要があります。

コレクション、その下に複数のドキュメントが紐づく形となっており、柔軟なデータ構造を構築できます。

速度的には単純なものであればすごく早いです。 しばらくリクエストがないと休止状態になっているのか少し時間がかかりますが、連続でリクエストするととても早く動作も安定しています。

クエリによるデータの取得

以下のような点で注意が必要です。

「!=」は使えない

クエリを使ってコレクション内のドキュメントを絞り込んで取得するのですが、「=」や「>」なんかは使えますが、「!=」は利用できません。 説明では「>」の結果と「<」の結果を合わせることで実現できると書かれていました。ちょっと不便ですね。

ただ、「!=」を使うことがそもそもNoSQL的には良くない操作のように感じました。ドキュメントのIDのを指定して1件のみを取り出して実現する仕組みを考えたほうがいいです。

Firebaseの料金プラン的にも、Firestoreで取り出したドキュメントの読み取り件数がカウントされています。「!=」のように大量のドキュメントを取得するかもしれない操作は避けたほうがいいです。少なくともlimit付けるようにしたほうが良いかなと思います。

「count」も工夫が必要

上記の取得件数によって料金が決まることがあり、ドキュメントの件数を取得するのにも工夫が必要です。 クエリに「count」はありませんので、普通にやるのであれば全件取得して、プログラム側でlengthを取得することになります。 これではFirebaseの従量にも、端末のメモリにも大きく不可を与えてしまうので避けたほうが良さそうです

公式では「分散カウンタ」と呼ばれる方式をおすすめしていました。ややこしいですが、件数が増える度に数を記録する用のコレクションに複数のドキュメントを作成しておく、というものです。

分散カウンタについて

  1. ドキュメントが書き込まれると、件数用コレクションのドキュメントの数値を1インクリメントする。countする場合はその件数用のドキュメント1件を読み取ることで取得。
  2. しかし、Firebaseにはドキュメントは更新後、1秒間は更新出来ません。上記のインクリメントはリアルタイムでの更新が多いと大きなボトルネックになってしまいます。
  3. そこで、件数用コレクション内にドキュメントを複数個用意します。ドキュメント書き込みの際にはこれらのどれかをインクリメントします。countを行う際はこれらの複数個のドキュメントを取得して数値を足し合わせて取得します。
  4. これによって、書き込み時のボトルネックは用意したドキュメントの数分軽減されます。読み取りの際はドキュメントの数分の読み取り件数が消費されますが、固定値にできます。

おわりに

こんな感じで、RDBとは似ているようで異なる概念になっており、使い勝手が大きく異なります。 今までの経験からRDBの利用方法を前提として考えてしまいがちですが、そもそもの仕組みが異なりますので、一度頭を空っぽにして設計してみることが大切だと感じます。

NoSQLで得意なことや、推奨されている使い方。パフォーマンスの面など知りたいことがたくさんです。

何よりサーバ側の管理等がとても楽になるのは大きいです。RDBではないことでやりにくいこともありますが、Firestoreによる制約を考えながら設計することも結構よし設計に貢献したりします。

無料でもある程度は利用できますので、Firebaseの他の機能についてもドンドン使っていこうと思います。

  • このエントリーをはてなブックマークに追加