モバイル開発において、端末ごとの同期をどのようにして行うか?
モバイルアプリの開発において、端末毎のデータの同期をどのように実装するのかについて考えてみました。
マルチプラットフォーム、複数端末でサービスを提供する場合、ユーザーアカウントを用意してサーバー側に全てのデータを保持し、 クライアント-サーバー間で通信を行うのが一般的かと思いますが、 個人アプリではあまりリソースを掛けたくないので、悩ましい感じです。
アニマネでもいずれ実装することになるので、現状の選択肢をまとめてみました。
長いので結論だけ先に書くと、AWS、Azure、FirebaseあたりのBaaSを利用するといいんじゃないかなという話です。
アニマネで実装する場合の前提条件
- 個人アプリなので規模はそれほど大きくない。
- 現状では複数端末で利用しているユーザーは少数。
- 需要は少数だが、ユーザーとしてはヘビーユーザーにあたるので大切にしてあげたい。
- ユーザー認証は基本的にfacebookやGoogleなどの外部アカウントで済ませたい。
- ユーザーの個人情報(ID/PASS)はあまり自前で管理したくない。
- サーバー側の開発にあまりコストは掛けたくない。
- iOS端末だけでなくAndroid端末も含めて同期が取れるようにしたい。
- 安いVPS内で色々動かしているので、ハードのリソースは不足気味。
実装時の懸念事項
- アカウントを保持することに伴うセキュリティリスク。
- 端末間での同期の確実性。
- オフライン時に使えるか。
アカウントの保持方法
企業レベルであればマーケティング的にも自社で持つのがいいと思いますが、 個人レベルではあまり保持したくないのが正直なところです。
認証については自前のサーバーで持つならOAuthで外部アカウントの利用オンリーにしたいところです。 BaaSを利用するなら、ID/PASSの保持も検討していいかなと考えています。
データ形式
次はデータの保持形式。 アニマネの場合、現状ではユーザーの設定情報をSQLiteに保存しています。
Webもアプリも提供しているのであれば、サーバー側に保持しているので、 特に悩む必要はないと思いますが、アニマネのようにアプリだけでデータを保持していると悩ましいです。
サーバー型DB
- MySQL等のRDBを利用する手法。
- サーバー側にAPIを用意して、その都度通信を行うオーソドックスな手法。
- ユーザーデータが必要になった時にその都度通信を行うので、同期の問題は心配しなくても済む。
- オフラインだと使えない。
- 開発コストはそれなりに掛かる。
- サーバー側のリソースも考慮する必要がある。
- Webでも提供しているサービスなら既にサーバー側でデータを保持しているはずなので、ケースによっては手軽に導入できる。
スタンドアロン型DB
- SQLiteやRealmなどのアプリ内で保持しているDBを同期する方法。
- 保存場所は自前のサーバーかS3などのストレージになる。
- 同期手法としては、一旦サーバーを介してDBファイル自体をやりとりする。
- ユーザーの設定情報が含まれるので、セキュリティには多少気を使う。
- オフライン時でも使えるが、オンラインになった時に同期する必要があったり、コンフリクトの問題など、アプリ側の開発に手間が掛かる。
- 開発の手間はBaaSの利用である程度は軽減できそう。
JSONなどのファイル形式
- 形式としては手軽。
- アニマネの場合はSQLiteからJSONにエクスポートする処理と、逆にインポートする処理を実装する必要がある。
- データ量が増えると厳しくなってくる。(アニマネの場合はそれ程多くはないので、耐えられるかもというレベル)
- プレーンな形式なので、マルチプラットフォームを考慮すると、SQLiteなどのDBよりはよい選択肢になりそう。
- それ以外はスタンドアロン型DBと同じメリット/デメリットがある。
サーバー型DBとスタンドアロン型DBのハイブリッド
- マスターデータはサーバー側で保持
- 起動時などに最新のデータをアプリ内のDBに取り込む。
- アプリ終了前か起動中にデータをサーバーに送る必要がある。
- コンフリクトなどの同期の対応が面倒になりそう。
- アプリ内ではDBを保持しているので、ある程度のデータ量なら問題なく対応できる。
- ゲームとかでよく利用されている手法(な気がしています。)
- サーバー側でデータを保持しつつ、オフラインでも利用可能なのは魅力的。
- 開発コストが高い。(BaaSなどで開発コストが吸収できればそこまででもない気がする)。
利用できそうなBaaS
自前での開発はコストが高いので、個人でやるならBaaSの利用がベターかと思います。
Dropbox API
https://www.dropbox.com/developers
Dropbox Sync APIというズバリのものがあったのですが、残念ながら終了とのこと。 同じようにDropbox Datastore APIというデータストアみたいなものもあったのですが、こちらも終了。
現在のAPIでは単純なファイルアップロード/ダウンロードはできるので、 ストレージとしては使えるみたいです。
一番面倒な端末毎の同期やオフライン時の処理、コンフリクトの問題は自前で実装する必要があるのは残念です。 Dropboxユーザー縛りになりますが、無料で使えるうえ、データの保存場所として丸投げできるところはよいかと思います。
Google Drive、SugarSync、OneDriveなどのクラウドストレージ系もAPIがあるようなので、Dropboxと同様に使えそうです。
アカウント認証を兼ねつつ、ユーザー側の領域に保存できることがメリットになります。
Amazon S3などのストレージサービス
SQLiteやJSON等のファイルを保持する際にはS3などのストレージサービスは使えそうです。
Dropboxなどとは違い、ユーザー側には保持しない分セキュリティ管理のコストは高まりますが、 自前でストレージを用意するよりは下がります。
アカウント認証は別途用意する必要がありますが、最近のBaaSは大体一緒に提供されているので、 大きな問題にはならないと思います。
サーバー側は楽できますが、端末毎の同期は自前で作る必要があります。
その他データストア系のサービス
単純なデータストアを提供するだけのBaaSはたくさんあるので、ここでは特に比較しません。 ファイルストレージと同様に端末間の同期を自前でつくることがネックになります。
Firebase
サーバー側にDBを提供しつつ、同期処理もSDKで行なってくれるので、 今回の要件にはマッチしそうです。
ユーザー側のデータはFirebaseに保持した場合、アプリ内のDB(自前サーバーから配信しているSQlite)との連携は一工夫必要ですが、 同期処理を実装するよりはコストが低いと思います。
ユーザー認証機能もあるので、その辺も含めてまとめて楽できそうです。
ただ、データを完全にFirebaseに預けることになるので、サービスが終了した時を考えると怖いです。 個人アプリなのでその辺のリスクを踏まえた上で楽してもいい気はしますが、 Parse.comのような運命を辿ると移行が大変そうです。
FirebaseはGoogleが買収しましたが、Facebookが買収したParse.comが終了になったことを考えると少々怖いです。
Microsoft Azure Mobile Apps
MicrosoftのAzureはFirebaseと同様にデータストアでのオフライン同期が提供されています。 iOSはCoreData,AndroidはSQLiteにローカルデータを保持し、変更があった時だけサーバー側にデータを送るようです。
ドキュメントによるとローカルデータの形式は独自で実装することもできるようで、使い勝手はよさそうです。
内部的にはOS標準のストレージを利用しているので、既存環境との連携も楽できそうです。
AWS Mobile Hub
AWS Mobile HubはAWSのいくつかのサービスを組み合わせて構成されています。
端末間の同期もできるようなので、今回のケースにも使えそうです。
内部的にはAmazon CognitoとAmazon S3で構成されているので、 Firebase同様にデータストアとして使うことも、プライベートなS3にSQLiteやJSONファイルを保存して同期することもできそうです。
雑感
現状では自前で実装することを考えると、Firebase,Azure,AWSあたりから選ぶのがよさそうでした。
今回は料金に関してはあまり考慮に入れてなかったので、 この中からアプリの利用状況に応じてマッチするサービスを選ぶのが良さそうです。
Firebaseは無料で利用することもできるので、個人アプリには強い味方になりそうです。
ただ、データストアにしてしまうと移行する時に大変そうなので、 その場合はAWSでSQLiteなりJSONなりを保持するパターンがよさそうです。
ただ、実際に使っている人の話をあまり聞かないので、実際の利用には不安もあります。 ドキュメント全般は日本語にも対応していてボリュームも結構あるので、その点は安心できそうな感じでした。
Microsoftなのでさすがに一定の品質は保っていると思いますが、 ググると検索結果に出てくるページが全部公式ドキュメントだったりと、情報が少ないのは不安です。
アニマネで実装するのは少し先になりそうなので、 もう少しじっくり様子を見ながら考えていきます。