Firebaseを使うと簡単にユーザ属性毎のプッシュ通知が送れて既読管理やコンバージョンも簡単に把握することが出来るよ！しかも無料で！すごく魅力的だけどめっちゃハマった話 

Firebaseを使うと簡単にユーザ属性毎のプッシュ通知が送れて便利機能も色々付いていてすごく魅力的なのですが、情報が少なくてハマった話です。
※本稿ではiOSやAndroidへの実装方法には触れません
# TL;DR
- Firebaseのプッシュ通知はアプリインストールユーザ全員に対してプッシュ通知を打つのは超カンタンなのにタイムゾーンも考慮してくれる優れもの
><img width="600" alt="push" src="https://qiita-image-store.s3.amazonaws.com/0/68048/eb2d0063-aabe-e31a-773c-824ba46ed250.png">

- アプリのバージョンや言語を分けてのプッシュも超カンタン
><img width="600" alt="スクリーンショット 2016-06-01 1.02.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/72d7e1c4-c3be-374e-ef6c-0f4559248832.png">

- 既読(起動)管理やコンバージョンも測定できちゃう
><img width="446" alt="スクリーンショット 2016-06-01 1.09.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/2b9da16b-355c-1b6c-ec9d-c04115948755.png">
<img width="450" alt="スクリーンショット 2016-06-01 1.09.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/e88f322f-3e8a-81f7-032c-33d8ff9643ac.png">

でも…

- 10人以上利用者がいないと数値が出なくて確認できないってハマるよ
- ユーザ属性に注意しないとハマるよ

　

- **導入できる人はとりあえず使ったほうが良いと思う**


# Firebaseって何なのか
元々はこんな感じのコンソールでリアルタイムデータベースを主軸としたサービスでした。
><img width="627" alt="スクリーンショット 2016-06-01 2.20.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/dd5512a1-8a89-f815-de41-be1993873ea0.png">


主な使用方法としては、webやios、androidなど各種プラットフォームのアプリにてこのデータベースをウォッチして、誰かが変更を加えると即座に反映される、といった、リアルタイム同期を提供してくれるデータベースBaaSでした。
類似のBaaSは他にも幾つかあるのですが、Firebaseはライブラリとサンプルがしっかり出来ていて導入コストが低いイメージです。またjson形式で定義するアクセスルールも柔軟性がありしっかり定義出来るので本番サービスへの導入も問題なく出来ています。

# Firebase2.0でこんなに変わりました
先日のGoogle I/O 2016でFirebase 2.0の発表があり、BaaSからモバイルのプラットフォームへと進化を遂げました。
今までの主軸であったRealtime DatabaseがFirebaseの一機能となり、色々と増えています。そしてその中央がAnalyticsとなっており、分析を中心としたプラットフォームになった感があります。
><img width="812" alt="スクリーンショット 2016-06-01 2.26.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/fbab7d2b-9a07-22f2-948d-92859b3fca0d.png">

動画もあります。
>[![firebase](http://img.youtube.com/vi/fgT6r4f9Apc/0.jpg)](http://www.youtube.com/watch?v=fgT6r4f9Apc)

# アナリティクス凄いよ
まずはこちらを見て下さい。
>![image01.png](https://qiita-image-store.s3.amazonaws.com/0/68048/970077ed-7288-fdbc-1496-84805a6c28e9.png)

なんとなく、凄い気がするというのは伝わったかと思います。
このアナリティクスには色々と機能があり、
GAでもおなじみのイベントや、
><img width="600" alt="スクリーンショット 2016-06-01 2.51.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/54eb6b4b-03b0-8413-f365-349217530462.png">

そのイベントをコンバージョンとしたときの数値を見ることが出来ます。
> <img width="600" alt="スクリーンショット 2016-06-01 2.51.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/ab4851ac-dea2-bb38-ca1e-8e05cc1d158c.png">

凄いのはここからで、ユーザプロパティという機能があります。
これは例えばユーザの登録状態であったり、使用言語といったユーザに関する属性を設定できるものなのですが、これを設定すると、
><img width="600" alt="user1" src="https://qiita-image-store.s3.amazonaws.com/0/68048/bc494495-daf5-4da4-8be6-4bb739388929.jpeg">

そのプロパティを使ってこのようなユーザリストを作ることが出来ちゃいます！
><img width="600" alt="user2" src="https://qiita-image-store.s3.amazonaws.com/0/68048/cf5da279-8864-83e2-f912-48cc8784d417.jpeg">

こんな風にiphone最新ユーザに絞るようなリストも作れます
><img width="600" alt="スクリーンショット 2016-06-01 2.53.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/0484b881-7922-7545-15c4-69759d5e8503.png">
<img width="600" alt="user3" src="https://qiita-image-store.s3.amazonaws.com/0/68048/e381328a-bf25-c64d-3554-ebf8143bfab7.jpeg">


## [ハマりポイント] All Users以外のイベントのユーザが0だけど何で？
プロパティを設定してイベントもちゃんと送信できているのになんでユーザが増えないのか？！
めっちゃハマってドキュメントも漁りまくった挙句に見つけました…Firebase Google Groupの一回答として…。
>https://groups.google.com/forum/#!searchin/firebase-talk/audience/firebase-talk/6v2ueLL-07o/PZYLS6ONGAAJ
 Also, the membership count is thresholded for privacy reasons, so if your audience has less than 10 users in it, it will display a count of 0.

なんと！プライバシー上の理由から10ユーザ以上にならないと0のまま！ドキュメントに書いておいて欲しい…。



# プッシュ通知凄いよ
前置きが長くなりました。
このユーザリストを用いることにより、特定のユーザ層めがけてプッシュ通知を送ることが出来るのがFirebaseの凄いトコロ！
こんな感じで、Analyticsのユーザリストからユーザ層を選択して送ることが出来ちゃいます。

登録済みユーザに対して送ったり、
><img width="679" alt="スクリーンショット 2016-06-01 3.06.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/e4d880b6-d0a4-375f-7ec8-87d855fe9e10.png">

iphone最新ユーザに対して送ったり。
><img width="675" alt="スクリーンショット 2016-06-01 3.07.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/bb107696-d719-c37c-240b-032a41a5ba23.png">

ユーザー層以外にも便利機能があります。

既読(起動)管理やコンバージョンも測定できちゃう。
><img width="446" alt="スクリーンショット 2016-06-01 1.09.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/2b9da16b-355c-1b6c-ec9d-c04115948755.png">
<img width="450" alt="スクリーンショット 2016-06-01 1.09.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/e88f322f-3e8a-81f7-032c-33d8ff9643ac.png">

他にも全世界対応のアプリには必須の、タイムゾーンを考慮した予約通知だったり、
><img width="600" alt="push" src="https://qiita-image-store.s3.amazonaws.com/0/68048/eb2d0063-aabe-e31a-773c-824ba46ed250.png">

アプリのバージョンや言語を分けてのプッシュも超カンタンにできちゃいます。
><img width="695" alt="スクリーンショット 2016-06-01 1.02.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/72d7e1c4-c3be-374e-ef6c-0f4559248832.png">


## [ハマりポイント] ユーザリストの罠
ユーザ属性を活用したプッシュ通知が便利すぎて心躍ったのも束の間、現状の仕様的に(2016/6/1)、使えない場面があることに気づいてしまったのであった…。

初期状態では全員未登録ユーザに設定されて、会員登録処理を行うと登録済ユーザになるといったシステムを構築しており、ユーザリストでは以下の2つを設定していました。

|リスト|条件|
|---|---|
|未登録ユーザ|register_statusがunregistered|
|登録済ユーザ|register_statusがregistered|

初期状態においては、

- 未登録ユーザリストにプッシュ通知を送る：受信！
- 登録済ユーザリストにプッシュ通知を送る：受信しない！

を確認出来たのでこれは凄い！と興奮したのも束の間、
会員登録処理を行って登録済ユーザになったときに事件は発生しました。

- 登録済ユーザリストにプッシュ通知を送る：受信！yeah！
- 未登録ユーザリストにプッシュ通知を送る：受信！?why...

期待していたのとなんか違う…ということでStackOverflowで確認しました。

>http://stackoverflow.com/questions/37450256/is-there-a-way-to-create-an-audience-of-developer-builds/37473026#37473026
Once a user is in an audience they will never be removed again regardless of if they qualify (or stop qualifying) for those conditions. 

一度ユーザリスト(audience)に入ると永久に削除されないよとのことです。現状の仕様的には。(2016/6/1)
なので、先ほどのように、一度未登録ユーザリストに入ってしまうと、その後登録済ユーザリストに入っても未登録ユーザリストに入ったままになってしまうのですね。

※**現状の仕様的には**と書いているのは、Google Analyticsのカスタムディメンションでは、
><img width="280" alt="スクリーンショット 2016-06-01 1.31.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/7eefc415-96d8-7f87-19e6-6e7068ae3cec.png">

というように、ヒット/セッション/ユーザーとカテゴリ分けされていて、ユーザーを選択するとそのユーザーの属性を過去に遡って変更してくれるので、追々そういったことも実装されるんじゃないかなーという**淡い期待**を持っています。長々と説明していますが、あくまでも**ただの期待**です。(中の人何卒よろしくお願い申し上げます！）

## 罠の裏側
さて、淡い期待（しつこい）をしているこの罠ですが、裏側をちょっと探ってみようと思います。

まず、ユーザリストのベースとなるユーザプロパティ（登録済みや、iosのバージョンなど)ですが、プロパティをセットするだけでユーザリストに入るというわけではなく、イベントに対してプロパティが付加される形式となります。（公式ドキュメントにも記載があります）

```swift
// プロパティセット処理例 これを呼んだだけではユーザリストに入らない
FIRAnalytics.setUserPropertyString("unregistered", forName: "register_status")

// イベント送信処理例 ↑を呼んだ後にこれを呼ぶと、このイベントに対して、{"register_status": "unregistered"}のプロパティが付く
FIRAnalytics.logEventWithName("sc_content", parameters: [
  "name": "tap",
  "full_text": "button"
  ])
```

察しの良い方はこれでピンと来るかと思いますが、イベントにプロパティが付くため、その後該当のプロパティを変更した（例えばunregisteredからregisteredに変わった）として、unregisteredだった時のイベントが削除されない限りは、未登録ユーザリストに残ったままになるという仕組みです。※イベントは削除されません

更に、FirebaseAnalyticsはbigqueryと連携出来て、連携すると流れているデータを自動的に出力してくれます（2日程度ディレイするようです）ので、スキーマを確認してみましょう。
※このデータを用いて自サーバに保存されているデータと突き合わせて色々処理するなんてことも勿論出来ますが、本稿ではその部分は端折らせて頂きます。
><img width="512" alt="スクリーンショット 2016-06-01 3.15.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/6822769a-300f-a850-a969-ed738d8db75f.png">

なんか、とても長いですね😨
これから言えることを簡単に説明すると、

- 日付毎にテーブルがローテーションされて、
- ユーザ属性とイベントが一つのレコードとして登録される
- ユーザ属性にはプロパティの他、端末情報も付加される。

といった構成になっています。

この構成において、ユーザ属性からプッシュ通知の対象を取得するというのは単純なクエリを書けば出てくるわけですが、
例えばアメリカのユーザに対してプッシュ通知を送りたいとなった場合にこのようなクエリを書くことで対象ユーザを取得することが出来ます。（本来はユニーク処理も必要です）
><img width="600" alt="スクリーンショット 2016-06-01 3.35.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/6c9af819-d2d7-d157-6021-f9ac0dbccee7.png">

同じく、日本のユーザに対して送ろうとする場合はこのようになります。
><img width="600" alt="スクリーンショット 2016-06-01 3.37.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/68048/7af04168-46e4-5161-df07-4ce0680576a0.png">

アメリカの場合と同じですね。
見づらいですが注目してもらいたいのが日米それぞれ一番下のレコードをみてもらうと分かる通り（一部隠していますが）、日本とアメリカで分けたにも関わらず同一ユーザが取れてしまっていることを確認できます。


さて、BigQueryの例を出してみたは良いもののちょっと複雑なので簡単なテーブルで考えてみましょう。

例えば5/31の時点ではこういったデータだったものが、

|ユーザID|国|params|event|
|---|---|---|---|
|1|JP|{"name": "foo"}|"tap1!"|
|2|JP|{"name": "var"}|"tap2!"|
|3|US|{"name": "Jon"}|"tap3!"|
|4|US|{"name": "Ray"}|"tap4!"|

6/1になって、ユーザ4のRayが日本に移住した例を考えましょう。そうすると、理想的な状態としては

|ユーザID|国|params|event|
|---|---|---|---|
|1|JP|{"name": "foo"}|"tap1!"|
|2|JP|{"name": "var"}|"tap2!"|
|3|US|{"name": "Jon"}|"tap3!"|
|4|JP|{"name": "Ray"}|"tap4!"|

こうなのですが、実際は、イベントとして追記される形になるので、

|ユーザID|国|params|event|
|---|---|---|---|
|1|JP|{"name": "foo"}|"tap1!"|
|2|JP|{"name": "var"}|"tap2!"|
|3|US|{"name": "Jon"}|"tap3!"|
|4|US|{"name": "Ray"}|"tap4!"|
|4|JP|{"name": "Ray"}|"tap5!"|

こうなってしまうので6/1になると、ユーザ4のRayは日本ユーザリストからもアメリカユーザリストからも見えることになってしまうという事になります。



## 使える場面を整理しよう
じゃあどういった場面で使えるかというのを整理しましょう

1. 全員に送る
 - これは言わずもがなですね。
2. 特定バージョンをインストールしているユーザに送る
 - 例えばバージョン2は致命的なバグがあってとにかくバージョンアップして欲しいとか
 - 最新バージョンでしか有効でない機能に対する通知とか
 - 特に問題なく送れると思います
3. 言語ごとに送る
 - 日本語ユーザには日本語で送って、それ以外は英語で送るとかありがちですね。
 - たまに送れないことがあります（調査中）
4. 「経験」系の属性
 - コインを購入したことが“ある”
 - ５回以上コメントしたことが“ある”
 - 投稿したことが“ある”
 - など、ユーザ毎に一度しかないイベントを用いた属性は問題なく活用できます
5. 一度設定したら二度と変更出来ない設定（ほとんど不変とみなして良い設定）
 - ちょっと良い例が思いつかないのですが、例えば出身地とか（ほぼほぼ変化することはないですよね）
 - 属性が変化しない限りはこういったものも活用できますね

逆に、変更が容易に想定される属性は活用できません。
居住地とか、独身/既婚とか、賃貸/持ち家とかとか。（もっといい例あったら教えて下さい）


# 今後のアップデートに期待しよう！
>https://stackoverflow.com/questions/37485583/differences-between-firebase-and-google-analytics/37485584#37485584
On a side note, keep in mind that Firebase has just launched and Google has plans on adding more features in the coming weeks (e.g., real-time dashboard).

Google Analyticsにあるようなリアルタイムダッシュボードなんかも来るそうですよ！
今後も続々アップデートがありそうな気配なのでこれから楽しみですね。


# 最後に
Firebase、すごいです。発表からもう2週間弱経過していますがまだ興奮が冷めやりません。
**導入できる人はとりあえず使ってみて色々共有しましょう！**
※本稿へのリンクも大歓迎です😄


# Firebaseの情報収集はここを✔
- 公式ドキュメント
https://firebase.google.com/docs/
- slack
https://firebase-community.appspot.com/
- Stack Overflow
https://stackoverflow.com/questions/tagged/firebase
- Google Groups
https://groups.google.com/forum/#!forum/firebase-talk
- そしてもちろんQiita
http://qiita.com/tags/Firebase