継続は「力」なり[Firebase+Android]

こんにちはSpeeeエンジニアのid:eva-hashimotoです。 先日行われたSpeeeKaigiで発表しました内容を記事にしたいと思います。

tech.speee.jp

今回の発表内容として去年末から年齢による体力の衰えを感じてジムに行き始めたんですが、 ふと気づくと最近やたらと筋トレブームがきているのとyoutubeなどの動画解説が充実しているので充実した筋トレライフが送れています。

そこで筋トレするにあたりトレーニングメニューや私が行っているエニタイムフィットネスの情報などを管理できるアプリがあれば便利だなと感じているわけです。

バックエンド

アプリ開発と同時にサーバサイドも開発すると工数がかかるのとアプリ開発に集中したいため、バックグラウンドにはMBaaSのFirebaseを利用しAndroidアプリの開発を行いました。

※今回はJavaで書いてます

仕様

  • トレーニングメニューの設定
  • トレーニングの履歴
  • トレーニング内容の分析

将来は食事管理や体重管理などできたらと思ってます。

Firebaseとの接続

Firebaseでプロジェクト作成をするとgoogle-service.jsonが自動生成されます。それをAndroidプロジェクトのappフォルダ直下に配置します。

build.gradle(app)のdependenciesに追加

    compile 'com.google.firebase:firebase-database:10.2.6'

データベース接続

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference databaseRef = database.getReference("history");

google-service.jsonにプロジェクト情報が入っているため、ソースコードにはデータベースのスキーマ??の接続情報だけで大丈夫です。

データ登録

データベースはリアルタイムデータベースを使い、リモートDBと同期して瞬時にデータ更新ができるようになります。 例えばトレーニングメニューの履歴登録では下記のようなModelになります。

    public String id;  // Firebaseが自動で入れるユニークID
    public String parts;  // 鍛える体の部位
    public String event; // トレーニング種目 
    public int weight;  // 重量
    public int lep;     // 回数
    public long timestamp; 

Firebaseにはタイムスタンプ型(Date型)がないためUnixtimeで登録します。

Training t = new Training("肩", "アーノルドプレス", 10, 5, System.currentTimeMillis());
databaseRef.push().setValue(t);

これでデータベースへ登録ができます。 f:id:eva-hashimoto:20170905180948p:plain

オンライン時には即時にローカル・リモートへDBが同期されますが、オフライン時にはローカルのデータベースに書き込まれ、回線が復活するとリモートへ同期されるなどとても便利です。

これをフルスクラッチで開発しなくて済むし、これだけのコード量で実現できるのでアプリ開発でMBaaSを利用しない手はないかと感じます。

トレーニング分析

トレーニングの履歴から傾向分析を行いたいと思うわけですが、リアルタイムデータベースを集計しダッシュボードを作成するのが普通だとお思います。 しかしダッシュボードや集計って運用していくと大変になってくるので今回はFirebase内にあるAnalyticsを使い分析することにして見ました。 ということでアプリないからカスタムメトリックストしてリアルタイムデータベースに登録している内容と同じものをデータ送信し、Analytisのダッシュボードで見ることをやって見ます。

アーキテクチャー

f:id:eva-hashimoto:20170906163006p:plain AnalyticsデータはBigQueryとも連携可能であるため、Analyticsでデータを見ることもできますし、アプリからCloudFunctionを利用を叩きリアルタイムデータベースに書き込むことでアプリでは非同期で集計結果が反映されるなどの仕組みも可能になります。

データの送信

FirebaseAnalytics fa = FirebaseAnalytics.getInstance(v.getContext());
Bundle params = new Bundle();
params.putString("parts_name", training.getParts());
params.putString("event_name", training.getEvent());
params.putInt("weght", training.getWeight());
params.putInt("lep", training.getLep());
fa.logEvent("event", params);

まとめ

このようにアプリのバックエンド、分析、クラッシュレポートなど多数の支援がFirebase煮詰まっているため、サーバサイドを意識することが減るのはメリットだと感じます。 またリアルタイムデータベースなども活用することでUIのリアクティブプログラミングとも親和性が高いと感じます。 これからアプリ開発ではMBaaSが主流になる可能性が高いと思いました。