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

第4回 データの保存をマスターする

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

前回の連載では,Firebase上に保存されたデータを用途に合わせてさまざまな方法で読み出してみましたが,データはすべてWebコンソールから用意していました。今回の連載では,クライアントアプリからさまざまな方法でデータをFirebase上に保存してみたいと思います。

今回も,前回同様,例として

/messages以下に,チャットのメッセージ情報を{"sender":"送信者", "body":"本文", "timestamp":"タイムスタンプ"}の一覧形式で格納

していきたいと思います。

データの保存方法

Firebaeでデータを保存する方法は次のにある4つです。

メソッド概要
setValue()特定のURIにデータを直接保存
updateChildren()特定のデータの一部要素だけを更新
push()リストに時系列にデータを追加
runTransaction()複雑なデータをアトミックに保存するためのトランザクション

順番に確認していきましょう。

setValue()

setValue()は最も基本的なデータの保存方法です。指定したURIにデータを直接書き込みます。すでに同一パスにデータが存在した場合はすべての情報を上書きします。

setValue()には保存する任意のデータ型をそのまま指定できます。メッセージを表現するデータ型として以下のようなクラスを定義してください。

public class ChatMessage {
    public String body;
    public String sender;
    public long timestamp;

    public ChatMessage(String body, String sender, long timestamp) {
        this.body = body;
        this.sender = sender;
        this.timestamp = timestamp;
    }
}

あとはデータの読み出し同様,任意のURIへの参照を取得し,setValue()メソッドを呼び出して書き込むだけです。

Firebase messages = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/messages");
message.child("01").setValue(new ChatMessage("How are you doing?", "Steve", System.currentTimeMillis()));
message.child("02").setValue(new ChatMessage("I'm great!", "Bill", System.currentTimeMillis()));

メッセージ一覧への参照を取得した後,child("01")のようにして1つ目のメッセージを格納するためのキーを作り,その下にメッセージを直接保存しています。2つ目のメッセージも同様です。

Webコンソールで確認して,以下のようなデータが保存されていれば成功です。

画像

完了コールバック

もしsetValue()で保存が完了したタイミングで何か処理を差し込みたい場合は,setValue()の第2引数にFirebase.CompletionListener()を渡すことで完了後にコールバックしてもらえます。

messages.child("01").setValue(chatMessage, new Firebase.CompletionListener() {
    @Override
    public void onComplete(FirebaseError firebaseError, Firebase firebase) {
        if (firebaseError != null) {
            Log.e(TAG, firebaseError.getMessage(), firebaseError.toException());
        } else {
            Log.d(TAG, "data successfully saved!");
        }
    }
});

エラー発生時にはFirebaseErrorが渡されるので,それの有無で処理を切り分けるといいでしょう。

以下のようにログに出力されれば成功です。

D/Firebase: data successfully saved!

updateChildren()

先ほどのsetValue()で大抵の場合は問題ないのですが,⁠送信者名だけを更新したい」といった一部のデータの更新にはsetValue()は向きません。setValue()は毎回すべての情報をまるごと書き換えてしまうからです。

このような用途にはupdateChildren()を利用します。

Map<String, Object> sender = new HashMap<>();
sender.put("sender", "Woz");
messages.child("01").updateChildren(sender);

このようにすると,senderだけをSteveからWozに書き換えることができます。bodytimestampはノータッチなので効率的です。

著者プロフィール

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

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

コメント

コメントの記入