LocoPartners 開発ブログ

LocoPartners 開発者達によるブログです

Firebaseを軽い気持ちで触ってみたら使い勝手が予想を遥かに超えてきた話

こんにちは。Loco Partnersのエンジニア、鈴木です。

わたくし普段は弊社サービスReluxのサーバーサイドの開発を担当していますが、元々はiOSエンジニアでした。
かれこれ1年近くも実務でのアプリ開発から離れているので、iOSは話題のキャッチアップで精一杯…。
たまには手を動かそう、ということで、話題のFirebaseをさわってみました。

Firebaseとは?

そもそもFirebaseとはなんでしょう?
元々は米国で始まったmBaasであり、2014年にGoogleに買収されたことでその名が広く知れ渡りました。
また先日のGoogle I/Oにてバージョンアップを発表、その中には無料で利用できるプッシュ通知の提供もありました。
年始に同じくプッシュ通知サービスを提供するmBaasであるParseの終了アナウンスがあったため、代替サービスとして注目している人も多いのではないでしょうか。
そんな時勢も相まって、今もっとも注目を集めるmBaasと言っても過言ではありません。

何ができるの?

f:id:loco-dev:20160627162600p:plain Firebaseは実に多くの機能を提供しています。
Authentication、Cloud Messaging、Crash Reporting、Notificationsなどなど、どれも本来であればサーバー開発に大きな工数がかかるもの。
これらの機能が高水準で提供されており、かつ無料で利用できる枠も大きいときたら、個人デベロッパーも企業も試さない手はないでしょう。

Realtime Database

f:id:loco-dev:20160704152603p:plain 今回は数ある機能の中から Realtime Database を試してみました。
便利そう、面白そう、かつフルスクラッチで作ったらとても大変そう、という理由です。
Realtime Database という名前からお察しのことと思いますが、特徴をざっくり箇条書きにするとこんな感じです。

  • 端末から送信されたデータがクラウド上に保存される
  • クラウド上のDBを介して、複数の端末、複数のユーザー間でデータの同期が可能である
  • オフラインでもローカル上でデータ保存され、オンラインになったタイミングで自動でクラウド上にデータ保存される

特に便利なのが最後のオフライン時の挙動。これをフルスクラッチで実現しようと思ったらぞっとしますね…。
たしかGoogle AnalyticsSDKがこんな仕組みだったと思うのですが、同じ技術を用いているのでしょうか。

導入編

それでは導入から見ていきましょう。
まずは登録から。
Googleアカウントと連携できるので、1クリックで完了です。
f:id:loco-dev:20160704154918p:plain

コンソールはこんな感じ。
ほとばしるGoogle感。
f:id:loco-dev:20160704155129p:plain

その後DLしたplistをプロジェクトに追加。 f:id:loco-dev:20160704160506p:plain

最後にCocoapods経由で追加してあげれば導入完了です。簡単ですね。
ちなみにpodfileへの追加分はこんな感じ。

pod 'Firebase'
pod 'Firebase/Database'

作るアプリ

複数端末でのデータ同期、ときたらやはりチャットでしょうか。
サンプルとして簡易的なチャットアプリを作ってみます。
最先端のマテリアルデザインを取り入れた、最高にイケてるUIです。
わかっているので何も言わないでください。
f:id:loco-dev:20160704161411p:plain

ユーザー名とテキストを入れるだけの、簡素なものです。

ソースコード

では実装に入っていきましょう。
AppDelegateに以下を追記します。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [FIRApp configure];
    return YES;
}

ViewControllerは以下。

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _nameTextField.delegate = self;
    _messageTextField.delegate = self;
    
    databaseRef = [[FIRDatabase database] reference];
    [databaseRef observeEventType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
        NSString *name = [[snapshot.value objectForKey:@"name"] stringByAppendingString:@": "];
        NSString *message =[[snapshot.value objectForKey:@"message"] stringByAppendingString:@"\n"];
        _textView.text = [_textView.text stringByAppendingString:[name stringByAppendingString:message]];
    }];
}

- (IBAction)submitBtn:(id)sender {
    NSString *name = _nameTextField.text;
    NSString *message = _messageTextField.text;

    [databaseRef.childByAutoId setValue:@{@"name":name, @"message":message}];
    _messageTextField.text = @"";
}

- (BOOL)textFieldShouldReturn:(UITextField *)sender {
    
    [sender resignFirstResponder];
    return true;
}

これですべてです。

やっつけコードなのはご容赦いただくとして、やっていることはこれだけです。

  • DBの読み書きをするためのインスタンスを取得
  • DBの変更を監視、変更があった場合の処理をブロック構文で書く(この場合はテキストの追加)
  • 送信ボタンが押下されたら、記入者とメッセージ内容を保存する

DBの読み書きが本当にシンプルに記述できます。

実行結果

それでは実行結果を見てみましょう。
f:id:loco-dev:20160704165655p:plain

コンソールにこんな具合で、リアルタイムにデータが追加されていきます。
ちなみに編集や削除もこちらからできます。debug時にも便利ですね。

今回シミュレータと実機でチャットを試してみましたが、問題なくやりとりできました。
また一方の端末でネットワークの接続を切って更新、ネットワーク再接続、というテストをしてみたところ、期待通り再接続時にもう一方でテキスト内容が更新されました。
意識することなくこれが実現出来るということだけでも Realtime Database のすごさがわかっていただけると思います。

総括

いかがでしたか?
繰り返しになりますが、その導入の簡単さ、記述するソースコードの簡潔さ、オフライン時の挙動の便利さには目を見張るものがあります。
今回はサンプルということで簡素な使い方しかしていませんが、色々とアイディアが膨らむサービスです。
次回は他の機能も試していこうと思います。