Firebaseのこれからとリアルタイムデータベースの補足説明

2016年6月22日(水)
清野 克行

本連載も今回で最終回です。今回は初めに5月18日~5月20日に開催された「Google I/O 2016」で発表されたGoogleのFirebaseに対する取り組みや新機能について紹介し、その後で本連載の補足解説として、FirebaseのRealtime Database機能についてサンプルプログラムと併せて解説します。

Google I/O 2016におけるFirebaseの紹介

GoogleがFirebaseを買収したのは2014年ですが、Google I/O 2016では筆者が確認しただけでもFirebaseに関連する18のセッションおよびスピーチがありました。いずれもGoogleのFirebaseに対する意気込みが感じられる内容で、ログ解析ツール「Firebase Analytics」やプッシュ通知サービス「Notifications」が無料・無制限で利用できることが注目を集めました。

Google I/ O 2016のオープニング基調講演では、FirebaseによってGoogleの開発ツールやサービススイートへの新機能の追加、既存機能の改良、さらにそれらの統合を強力に進めることが可能になったことが発表されています。

【Google I/O 2016での主なFirebase関係動画】

参考までに、Google I/O 2016における主なFirebase関連の動画を紹介します。

・Firebase Overview - Google I/O 2016

・The key to Firebase security - Google I/O 2016

・Grow your app with Firebase using Notifications, App Indexing, Dynamic Links - Google I/O 2016

・Use Firebase Analytics to Build Extraordinary Apps - Google I/O 2016

・Migrate to Firebase - Google I/O 2016

Google IO 2016のFirebaseスピーチ概要

GoogleはFirebaseを開発およびWebアプリケーション管理のための包括的なプラットフォームにしたいと考えています。Googleの通知プッシュプラットフォームは「Firebaseクラウドメッセージング」注1と呼ばれ、GCE(Google Cloud Platform)と連携します(図1)。開発者は高度にスケーラブルされたFirebaseストレージの柔軟なシステム上でメディアを保存でき、Firebaseリモートコンフィグにより新しいバージョンを公開することなくインストールされたアプリに変更を加えることができます。

FirebaseはGoogle Cloud Platformと連携する

図1:FirebaseはGoogle Cloud Platformと連携する

また、Firebaseはクラッシュレポート・ツールで確認する前に開発者自身がアプリの問題を発見できる「テストラボ」を装備しています。アドワーズ広告とAdMob注2というGoogleの2つの強力な広告プラットフォームは、今もFirebaseに組み込まれています。

※注1:デベロッパーがAndroid、iOS、Chromeといった複数のプラットフォームにメッセージを送信できる無料のサービス。 例えば、サーバーから1つの端末、端末グループ、または特定のトピックを定期購入している端末に直接メッセージを送信できる。

※注2:AdMobは、アプリ内に組み込めるアフィリエイト型の広告サービス。アプリにAdMobのSDKを組み込むことで広告を表示でき、広告がタップされると収入が得られる仕組みになっている。

Firebase Analytics

「Firebase Analytics」はモバイルアプリのために開発され、無料で無制限に使える分析ツールです。Firebaseプラットフォームの中核を成すFirebase Analyticsによって、成果を生むアプリを開発するために必要な分析情報が提供されます。

GoogleはFirebaseの機能拡張を実施した際にアプリ開発とアプリビジネスの発展をサポートできるよう、小規模なスタートアップ企業から大規模企業まで、あらゆる規模のアプリデベロッパーのニーズを満たす分析ソリューションの構築に力を入れています。

1つのソリューションであらゆるアプリ分析が可能

アプリ内でのユーザー行動を分析できるFirebase Analyticsには、必要なあらゆる指標(ユーザーあたりの平均収益額、アクティブユーザー数、ユーザー維持率、イベント数など)が備わっており、ユーザーによるアプリの使用方法を示すユーザープロパティデータ(デバイスの種類、アプリのバージョン、OS のバージョンなど)と組み合わせて分析できます。

データの収集は簡単で、複雑な設定は不要です。アプリにFirebaseを導入すると、初回起動(インストールと同様の指標)やアプリ内購入といった主要なイベントが自動的に測定されます。また、最大500種類のイベントを測定できる(イベントごとに最大25個のKey-Valueペアパラメータを設定可能)ほか、コードを数行追加すればアプリに固有の推奨イベントやカスタムイベントを測定することもできます。

アイテムの購入や他のユーザーとのアプリ共有など、顧客にとって他より価値の高いアプリ内イベントがある場合は、そうしたイベントをコンバージョントラッキングで定義し、専用の目標到達プロセスを設定すればユーザーがそのプロセスのどこで離脱しているかを把握できます。

Firebase Analyticsの機能はユーザー行動の分析だけではありません。地域情報やユーザー属性、ユーザーの興味や関心といった豊富なデータセットを使って分析することでアプリの機能を改善し、マーケティングの取り組みを効果的に改善できます。アプリ分析には標準的なユーザー属性データも役立ちますが、アプリに固有のユーザープロパティを把握することも重要です。例えば、アプリのすべてのユーザーにカスタムなユーザープロパティを設定して、フィットネスアプリであれば各ユーザーの好みのエクササイズを記録したり、音楽アプリであれば各ユーザーのお気に入りのジャンルを記録したりできるのです。

また、Firebase AnalyticsはGoogleが完全管理するデータウェアハウス「BigQuery」注3とも統合されているため、Firebaseの生データをBigQueryにエクスポートすれば、カスタムデータを使ってさらに詳しく分析できます。

※注3:Googleは2016年6月2日にBigQueryの機能強化を発表。標準SQLのサポートに加え高度なクエリプランニングと最適化も可能となり、SQLステートメントで任意の複雑なサブクエリがかけられるようになった。さらに、日、時間、アレイ、構造体など幅広い型システムとTheta Joinもサポートされるようになった。

アプリマーケティングの効率と効果を向上

ユーザー行動の把握はFirebase Analyticsの重要な機能の 1 つですが、広告掲載やマーケティングによってユーザー行動にどのような影響が出ているかを把握するための機能も欠かせません。

Firebase Analyticsではアプリ内でのユーザー行動とトラフィックソースが自動的にリンクされ、価値の高いユーザーの参照元がわかります。Google AdWordsなど20種類以上の主要な広告ネットワークと連携して機能するため、新しいSDKを導入する手間をかけずにマーケティングや広告掲載の費用対効果を簡単に把握できます。

また、Firebase Analyticsのコンバージョンイベントを直接Google AdWordsにインポートすれば、アプリで発生する特定のユーザーイベントに個別の入札単価を簡単に設定することもできます。

Firebaseの要はFirebase Analytics

Firebase Analyticsでは、ユーザーリスト機能を使用してユーザーのイベントデータやユーザープロパティに基づいたユーザーセグメントを構築できます。

例えば、カートにアイテムを追加したが購入に至らなかったユーザーや、200 曲以上のクラシック音楽を聴いたユーザーなどのユーザーリストを構築できます。Firebaseのリモート設定機能でこうしたユーザーリストを利用すれば、指定したリストのユーザーだけを対象にアプリのデザインを変更できます。

さらに、ニュースレターを配信登録したユーザーやフィットネスアプリで一定レベルに達したユーザーなどに表示するホーム画面をカスタマイズすることもできます。こうしたアレンジは、Firebase Analyticsのリモート設定とユーザーリスト機能を使って直接Firebaseコンソールから行うことができます。

Firebase Analyticsのユーザーリストは通知機能でも利用可能で、任意のユーザーリストのみを対象にアプリ内通知を送信できます。例えば、ゲームアプリ内のショップに新しいアイテムを追加した場合、過去にアプリ内でアイテムを購入したユーザーだけにその情報を通知できます。

また、Firebaseアカウントを AdWordsアカウントにリンクすれば、広告キャンペーンのユーザーリストを使って最近アクセスのないユーザーにアプローチすることも可能です。

リアルタイムデータベースの補足解説

以降では、本連載の補足説明としてリアルタイムデータベースについて解説します。図2はFirebaseのメインフィーチャです。リアルタイムデータベースは本連載の主テーマとしてサンプルプログラムと基本的な機能を解説しましたが、ここでさらに掘り下げて見ていきます。

Firebaseのメインフィーチャ

図2:Firebaseのメインフィーチャ

FirebaseにはJSONでデータが書き込まれます。AndroidやiOS、JavaScript等でクロスプラットホームのアプリケーションを作成すると1つのFirebaseデータベースがシェアされ、書き込まれた最新データが自動的に受信できるようになります。なお、JSONで表現できる任意のデータ型は以下のとおりです。

  • String
  • Boolean
  • Long
  • Double
  • Map<String, Object>
  • List<Object>
  • およびこれらの再帰的なデータ構造

Firebaseでは、あるモバイルデバイスで書き込まれたデータがバックエンドのデータベースに保存されると同時に別のモバイルデバイスへも反映されるため、複数人で書き込むチャットやソーシャルメディアのようなアプリケーションを簡単に構築できます。使い方は、「データベースをオブジェクトとして宣言し書き込むだけ」という簡単なものです(リスト1)。

リスト1:オブジェクト宣言と書き込み

// Create a Firebase database reference
var ref = new Firebase('https://kseino.firebaseio.com/');   

// Save data
ref.setValue(“Hello firebase!”);

リアルタイムデータベースへのデータ書き込み時の留意点

リアルタイムデータベースはJSONフォーマットのNoSQLであり、データの書き込みには注意が必要な部分があります。それは「書き込まれたデータがその後読み込まれるときに、なるべくシンプルな処理手順で読めるようにすべき」という点です。そのためには、一般的に「データ構造をなるべくネストさせずに、可能な限りフラット化されたデータ構造で書き込む」ことで対処します(参考URL:)。

ネストされたデータ構造

データベースに書き込むデータは32レベルもの深さまでネスティングできます。しかしリアルタイムデータベース内のあるデータをフェッチ(検索)する場合には、対象データのすべての子ノードデータも取得されてしまいます。もし子ノードのデータがそのフェッチでは必要なく、またサイズが大きい場合には処理上の無駄が発生し、またフェッチパフォーマンスにも影響を与えることになります。

リスト2はネストされたデータの書き込みプログラム例です。(1)~(3)が書き込まれるデータのフォーマットですが、最も長い文字列になる可能性があるmessageがネスティングで最も深い場所にあります。

サンプルプログラム

次に、データ構造の違いをサンプルプログラムで見ていきましょう。使用するサンプルは図3のような画面で、この画面でネストされたデータ構造とフラット化したデータ構造の2種類のJSONフォーマットで書き込みを行ってみます。

2種類のJSONフォーマットでデータを登録

図3:2種類のJSONフォーマットでデータを登録

図3は本連載で使用した画面を一部修正したものですが、ポイントはタイトル下のメッセージ入力フィールドが拡張されている点でしょう。

ネストされたデータ書き込みのプログラムサンプル

実際にデータを書き込むプログラムはリスト2の通りです。(1)~(3)でJSONデータを書き込んでいますが、データ構造はネスティングされており、(2)のメッセージバリューを書き込む部分がネスティングの最下層にきています(参考URL:)。

リスト2:ネストされたデータの書き込みプログラム例(非推奨)

<!DOCTYPE html>
<html>
  <head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1" />                 <!--(1)-->
    <script type="text/javascript" 
         src="http://code.jquery.com/jquery-1.6.4.min.js"></script>                      <!--(2)-->
    <script src='http://cdn.firebase.com/js/client/2.2.1/firebase.js'></script>
    <title>Firebase Simple chat</title>
  </head>
  <body>
  <h1>Firebase Simple Chat</h1>  
  <p>名前   <input type='text' size="24" id='nameIn' />
     <input type='button' id='sendMsg' value='    書込み   ' /></p>      
  <p>住所    <input type='text' size="42" id='addressIn' /></p>
  <p>E-Mail <input type='text' size="42" id='emailIn' /></p>              
  <hr/>        
      タイトル<input type='text' size="42" id='titleIn' /><br/>      
  <textarea id='messageIn' rows='12' cols='70'></textarea>
  <hr/>       
       画面表示  :<p id='dtShow1'></p>
       登録処理  :<p id='dtShow2'></p>
       レスポンス:<p id='dtShow3'></p>
  <script>
  var ref = new Firebase('https://kseino.firebaseio.com/');   
  $('#sendMsg').click(function(e){
      var name1 = $('#nameIn').val();
      var address1 = $('#addressIn').val();
      var email1 = $('#emailIn').val();
      var title1 = $('#titleIn').val();
      var message1 = $('#messageIn').val();
      var date1 = getDate();
      var time1 = getTime();
      ref.push({"msgs":{                               //(1) JSONデータ開始
          "user":{
	        "name": name1, 
	        "address": address1, 
	        "email": email1,      
              "messages": {
   	            "wdate": { 
                          "date": date1, 
                          "time": time1,                          
   	                   "contents": {               
                               "title": title1, 
                               "message": message1   //(2)
                          }                        
                      }                    
                  }               
              }
          }
       });                                             //(3) JSONデータ終了
      $('#msgIn').val('');      
  });
  ref.on('child_added', function(snapshot){
    var msg = snapshot.val();
    dspChatMsg(msg.name, msg.dtime, msg.text);
  });
  function dspChatMsg(name, dtime, text){
    var dtime3 = getDtime();
    $('#dtShow3').text(dtime3);
    $('<div/><br/>').text(text).prepend($('<em/>').text(dtime +': ')).prepend($('<em/>').text(name+': ')).appendTo($('#msgDiv'));
    $('#msgDiv')[0].scrollTop = $('#msgDiv')[0].scrollHeight;      
  };
  function getDate(){
     var dt = new Date();
     var year = dt.getFullYear();
     var month = dt.getMonth()+1;
     var day = dt.getDate();
     var date1 = year+'年 '+month+'月'+day+'日 ';
     return date1;
  };
  function getTime(){
	   var dt = new Date();
	   var hour = dt.getHours();
	   var minute = dt.getMinutes();
	   var second = dt.getSeconds();
	   var millseconds = dt.getMilliseconds();
	   var time1 = hour+'時 '+minute+'分 '+second+'秒 '+millseconds+'ミリ秒';
	   return time1;
	};  
  </script>
    <div id='msgDiv'></div><hr/>
  </body>
</html>

リスト2でリアルタイムデータベースに書き込まれたデータは図4のようになります。「message:」にかなり長いオバマ氏の広島スピーチの一部が表示されています。

リアルタームデータベースに登録された図3の画面データ(ネスト化)

図4:リアルタームデータベースに登録された図3の画面データ(ネスト化)

ネスティングをフラット化したデータ書き込みのプログラムサンプル

次に、ネスティングをフラット化した場合のプログラムサンプルですが、プログラムの全体構造はリスト2と全く同じです。書き換えているのは(1)~(3)の部分のみです(リスト3)。

リスト3:推奨されるJSONデータフォーマット例

      // (1)  フラットデータへの変更
      ref.push({"user":{
          "profile":{
              "name": name1, 
              "address": address1, 
              "email": email1
           },
           "title": {title1
           },	   
           "message": {message1
           },	   
           "date":{ 
              date1, "time": time1 
           }
        }
      });   

リスト3ではJSONのデータ構造がかなりフラット化されており、実際にリアルタイムデータベースに書き込まれたデータは図5のようになります。

リアルタームデータベースに登録された図3の画面データ(フラット化)

図5:リアルタームデータベースに登録された図3の画面データ(フラット化)

このように、バリュー値として長文テキストなどが書き込まれるJSON オブジェクトはなるべく浅いネスティングに配置することがポイントとなります。

おわりに

Google I/O 2016の動画などを見てもGoogleがFirebaseにかなり注力していることが伺えます。またGoogle I/O のタイミングでFirebaseの画面構成も一新されました(図6)。

画面が一新されたFirebaseのホームページ

図6:画面が一新されたFirebaseのホームページ

FirebaseもこれからGCP(Google Cloud Computing)に配置される主要モジュールの1つとして、さらに機能が追加されると考えられます。詳細はFirebaseの公式ページを参照ください。

また、Firebaseはこれからさらに成長が期待されるツールです。今後も継続してFirebaseのニュースに関心を持っていただきたいと思います。

最後になりましたが、本連載をお読みいただき、ありがとうございました。

有限会社サイバースペース
慶應義塾大学工学部電気科卒。日本IBM、日本HPなどにおいて、製造装置業を中心とした業務系/基幹業務系システムのSE/マーケティングや、3階層C/Sアーキテクチャによる社内業務システム開発などに携わる。現在は、Ajax/Web 2.0関連のセミナー講師/コンサルティング、書籍執筆などを行っている。情報処理学会会員。http://www.at21.net/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています