お久しぶりです。株式会社mikanでソフトウェアエンジニアをしている @hoshitocat です。
先月末に更新しようと思ったのですが、更新が遅くなってしまいました。 4半期の終わりだったために、やることが多くブログの更新まで手が回りませんでした。 見積もりが甘かったです、、、
前回はFirebaseのプロジェクト移行したよという話をしました。 これのおかげで、長らく続いていたFirebaseのプロジェクトの2重管理が必要なくなり、とても幸せになりました。
さて、タイトル通りではありますが、英単語アプリmikanでは今後Firestoreを使っていくことにしました✌🏻
という話をしたいと思います。
Firestoreを使うか迷っているけどどうしようと思っている方の参考になればと思っております。
はじめに
弊社のiOSアプリは、 SQLite をアプリ内データベースとして使っています。
ちなみに、Androidアプリでは当時流行っていた RealmDB をアプリ内データベースとして使っています。
現在mikanでは、アプリ内データベースに保存されているデータをOS間で共有することができません。
実際にお客様からも「機種変更したときに、前の学習データを同期したい」といったお問い合わせを多くいただいております。
ユーザの利便性や今後アプリをより良くしていくためには 共有のための仕組み を構築する必要があります。
Firestoreを選択した理由
Firebaseの他に検討したものとして、
- RealmDBをiOSでも使い、Realm Syncを使う
- SQLiteをAndroid側に導入し、S3にファイルを直接アップロードして共有
- 共有用DBとそのAPIを構築する
がありました。
RealmDBがオフライン対応とデバイス間でのデータの共有が可能なので、Firestoreでやろうとしていることに近いかなと思いますが、 AndoirdのクライアントDBのデファクトスタンダードはSQLiteになりつつあり、 すでにバックエンドとして、FirebaseとGCPを使っていることもあったので、Firestoreを選択しました。
その他に関しては、オフライン対応をする必要があったため、 その仕組みを1から構築していくのは難しいし、 コストだと考え、選択肢から除外しました。
Firestoreはオフラインにも対応していて、クライアントのSDKも充実しており、すでにFirebaseを使っていることもあり導入が容易でした。
また、他にも強力な機能(例えば、セキュリティルールやリアルタイムリスナー、Firestoreの変更を検知してCloud Functionsを呼び出すなど)が揃っており、 導入事例もそこそこあったので、使っていくことにしました。
オフライン対応
英単語アプリmikanでは、地下鉄など電波の悪い状態でも学習が継続できるように、オフラインでの学習を可能にしています。 それを実現するために、アプリ内にSQLite, Realmというデータベースを使って、ユーザの学習データを保存しています。
そのため、SQLiteやRealmに保存されているユーザの学習データを共有するためには、
オフライン対応する上で必須となるのが、エラー処理です。
例えば、新しい学習データを保存する際に、その学習データを保存する際にエラーが発生した場合、 再度書き込み処理を実行する必要があります。
Firestoreでは、オフラインに対応のためのオペレーション・キューが実装されています。 オフライン時はこのオペレーション・キューに書き込み処理が蓄積され、 端末がオンラインに戻った際に、自動的に書き込みが開始されます。
また、書き込みエラー時の処理もFirestore側で実装してくれているため、書き込みエラーが発生することを想定した実装は必要ありません。
Firestoreを使ってみて良かったこと
想定どおり、書き込みや読み込みの際にオフライン時のエラー処理を気にせず、 扱えるというところが楽です。
セキュリティルールも非常に強力で、アクセスできるユーザだけでなく、バリデーションなどにも使えるので 非常に強力な機能です。
また、Cloud Functionsとの相性がとても良いので、Cloud Functionsをトリガーで実行することで、 変更を検知して非同期で処理を挟み込んだり、Firestoreの非正規化のデータモデルにも対応できます。
Firestoreを使っていての懸念点
もちろんいい事だらけではありません。
NoSQLなうえ、コレクションとサブコレクションという階層構造にデータを保持することができます。
通常のリレーショナルデータベースのように、正規化をすれば基本的にはうまくいくようなものではありません。
なぜなら、Firestoreには、集計や結合を行うためのクエリは用意されていないため、 これまでのリレーショナルデータベースで行えていた複雑なクエリによって データを扱うことが難しくなっています。
このような特性を活かすための設計が非常に重要になってきます。
まとめ
本日は弊社がFirestoreを使うことにした理由をお話ししました。
Firestoreは非常に強力な機能を備えている一方で、 設計の難しさはあります。
これから、この難しさにチャレンジした上で、 うまくいったことや失敗したことを発信していきたいと思っております。
次回は、SQLiteのデータをどうやってFirestoreに移行していったのかを書きたいと思います👨🏻💻
最後に
弊社では、一緒に働く仲間を募集中です!
教育事業へ興味のある方、技術的にもまだまだこれからのところでチャレンジしたい方、ぜひ少しでも興味ある方はご連絡ください!
実はこの前HPが完成したので、合わせてこちらもみてみてください 😸