スマホアプリ開発を加速する,Firebaseを使ってみよう

第2回 Firebase最初の一歩 ─簡単なデータの保存と読み出し

この記事を読むのに必要な時間:およそ 4 分

Androidクライアントからデータを読み出し

さて,いよいよFirebaseに保存したデータを読み出してみたいと思います。

Firebaseのデータを読み書きできるクライアントにはWeb,iOS,Android,REST等がありますが,ここではAndroidクライアントの例を紹介します。

セットアップ方法こそ各クライアントで違いますが,その後の読み出し方や概念等はほとんど同じと言って差し支えありませんので,Android以外のクライアントをご利用予定の方も是非読み進めていただければ幸いです。

Androidクライアントのセットアップ

Android用のFirebaseクライアントライブラリはMaven Centralレポジトリに提供されているので,Gradleで簡単に導入することができます。

Android Studioの場合はbuild.gradleに以下を追加してください。

dependencies {
    compile 'com.firebase:firebase-client-android:2.5.2+'
}

もしビルド時にDuplicate files copied in APK META-INF/NOTICE...等のエラーが出てビルドに失敗する場合はbuild.gradleに以下を追加してください。

android {
    ...
    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE-FIREBASE.txt'
        exclude 'META-INF/NOTICE'
    }
}

Firebaseはインターネットに接続するのでAndroidManifest.xmlandroid.permission.INTERNETパーミッションを追加してください。

<uses-permission android:name="android.permission.INTERNET" />

最後に,Firebaseの初期化処理を自前のApplicationクラスに定義します。

android.app.Applicationを継承したクラスを定義し,以下のようにFirebase.setAndroidContext(this);を記述してください。

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Firebase.setAndroidContext(this);
    }
}

独自Applicationクラスを定義したので,Androidアプリケーションがそれを参照するようにAndroidManifest.xmlapplicationタグにandroid:name属性を追加してください。

<application
  android:name=".MyApplication"
  ...>
</application>

以上でFirebaseのAndroidクライアントライブラリを使用する準備は整いました。

データを読み出し

それではデータを読み出してみましょう。

ここでは先ほどWebコンソールから追加した以下のデータが既にFirebase上に格納されている前提で,/users/shiroyama/nameに存在する値を読み出してみたいと思います。

{
  "users" : {
    "shiroyama" : {
      "name" : "Fumihiko Shiroyama",
      "address" : "Tokyo, JP"
    }
  }
}

データを読み出したい任意の場所(たとえばActivity#onCreate()内)で以下のようなコードを記述してみてください。前述のとおり<YOUR-FIREBASE-APP>の部分はお使いの環境で読み替えてください。

Firebase firebaseRef = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/");

firebaseRef.child("users/shiroyama/name").addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // "Fumihiko Shiroyama"
    Log.d("Firebase", snapshot.getValue().toString());
  }
  @Override public void onCancelled(FirebaseError error) { }
});

実行してログにD/Firebase: Fumihiko Shiroyamaと表示されれば成功です。

イベント駆動プログラミング

コードの解説をする前に,ここで興味深い実験をしてみましょう。Webコンソールで先程の"name" : "Fumihiko Shiroyama""name" : "John Smith"に変更してみてください。すると,Android側のコードは一行も変更せず,アプリをリビルドしたり再起動したりしなくても,

D/Firebase: John Smith

とログに表示されませんでしたか?

実はここで書いたコードは,利用者が能動的にデータを取得する「Pull型」の取得方法ではなく,データが追加/変更されたタイミングで通知される「Push型」の取得方法だったのです。このようなプログラミングパラダイムは「イベンド駆動プログラミング」と呼ばれ,Firebaseを利用したプログラミングの大きな特徴のひとつとなっています。

プログラマはその時々で欲しいデータを要求するのではなく,⁠こういう状況ではデータをこうしたい」という処理(コールバック関数やリスナと呼称されます)をあらかじめ登録しておくことで,将来の任意のタイミングで起こる追加や変更にリアルタイムに応答するリッチな体験をユーザに提供することができるのです。

コードの解説

Firebaseのプログラミングの特徴がわかったところで,先ほどのコードを詳しく見ていきましょう。

まず,1行目のFirebase firebaseRef = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/");の部分に注目してください。これはFirebaseの「reference(参照⁠⁠」と呼ばれ,これから読み書きするFirebase上のデータの場所を指し示しています。この例では,https://<YOUR-FIREBASE-APP>.firebaseio.com/だけ指定しているので,当該データベースのルート,つまりJSONツリーの1番てっぺんを指しています。

注意点として,この参照を作った時点ではいかなるデータの読み書きも発生していません。あくまでその位置を指し示しただけに過ぎません。

次に,2行目のfirebaseRef.child("users/shiroyama/name")の部分に着目してください。これは,先ほど作った参照の子ノードusers/shiroyama/nameを参照すると指定しています。つまりhttps://<YOUR-FIREBASE-APP>.firebaseio.com/users/shiroyama/nameに対してこれから読み書きをすると指定していることになります。

最後に,2~最終行のaddValueEventListener(new ValueEventListener() { })の部分に注目してください。ここでは「データが新しく追加されたり変更された場合に処理する内容(リスナ⁠⁠」を登録しています。データが追加されたらonDataChange(DataSnapshot snapshot){ }が呼ばれるというわけです。

では,DataSnapshotとは何なのでしょうか? また,データが追加/変更される以外にもイベントが追加されるタイミングはあるのでしょうか? このあたりは,次回で詳しく掘り下げていきたいと思います。

まとめ

今回は,Firebaseにサインアップし,Webコンソールでデータを保存し,Androidからそのデータを読み出す部分までを駆け足で見てきました。次回は,Firebaseからデータを読み出す方法についてより詳しく解説したいと思います。お楽しみに。

著者プロフィール

白山文彦(しろやまふみひこ)

サーバサイド,インフラ,Androidなど何でもやるプログラマ。