【Android】30分で実装するPush通知【Firebase】


30分もかからない可能性も微レ存

[Google I/O 2016](https://events.google.com/io2016/)でFirebase Analyticsの無料化が発表されましたね。
Analytics以外にも便利な機能がてんこ盛りで面白そうなので試してみたいと思います。
取り急ぎ使ってみたい機能として以下3つをさくっと動かしてみます。
・Analytics（セグメント別にPushできるそうなので入れておきます）
・Notifications（Push通知）
・CrashReporting（おまけ）

（2016/06/07追記）
[【Android】既存アプリにFirebaseを入れるときにハマった話](http://qiita.com/SnowMonkey/items/5b9019a936aa6762cf53)書きました


# Firebaseとは
Android/iOSアプリでAnalyticsが出来たり、Notificationの送信管理ができたり、Crashレポートやログイン時の認証機能なんかも盛り込んだいろいろできるスゴイ奴です。
詳しくは[この記事](http://jp.techcrunch.com/2016/05/20/20160518google-turns-firebase-into-its-unified-platform-for-mobile-developers/)とか[本家サイト](https://firebase.google.com/)とか、本家の[紹介動画](https://firebase.google.com/docs/analytics/)は日本語字幕付きで見られるのでおすすめです。
また、[githubにサンプルソース](https://firebase.google.com/docs/samples/)も公開してくれているので導入も簡単！

# Firebase登録
ログイン中のGoogleアカウントでそのまま登録されるのですが、めちゃくちゃ簡単に登録できて感動しました。
（メールアドレス入力して送られてくるメールからConfirmして…みたいなよくあるフローを駆逐したい）

## Firebaseプロジェクトの作成
[FirebaseのTOPページ](https://www.firebase.com/)から、「See our new website」→「GET STARTED FOR FREE」→「新規プロジェクトを作成」と進みます。
![Firebase_reg_comb_01.png](https://qiita-image-store.s3.amazonaws.com/0/109065/800469a8-eb37-4827-ce90-edf71b707450.png "Firebase_reg_comb_01.png")

プロジェクト名を（適当に）入れて作成すれば登録は完了です。
![Firebase_reg_04.png](https://qiita-image-store.s3.amazonaws.com/0/109065/7aa413dd-2665-e490-865d-3d4513252288.png "Firebase_reg_04.png")

登録後にプロジェクトのOverviewが表示されます。
![Firebase_overview.png](https://qiita-image-store.s3.amazonaws.com/0/109065/3d7519f0-6455-edc3-79c2-6ca13146d0c6.png "Firebase_overview.png")


## Firebaseプロジェクトにアプリを追加
今回はAndroidアプリを追加してみます。
Overviewにて「AndroidアプリにFirebaseを追加」を押すとパッケージ名を聞かれますので、サンプルアプリ作って試します。
![Firebase_add_app_01.png](https://qiita-image-store.s3.amazonaws.com/0/109065/916b8236-d320-3e0a-f7e2-ccaccd73939f.png "Firebase_add_app_01.png")

サンプルで作ったアプリのパッケージ名を入力します。
署名証明書はまだ使わないのでスルーしてよいです。
とても丁寧な手順があるのでその通りに進めます。やることはFirebaseのサイトが自動生成したファイルを追加し、build.gradleに2行追記するだけです。
![Firebase_add_app_combine_01.png](https://qiita-image-store.s3.amazonaws.com/0/109065/852f7b51-3af8-db52-6e8f-2cbcd2ef4537.png "Firebase_add_app_combine_01.png")

「終了」まで進むとFirebaseプロジェクトにアプリが追加されています。
![Firebase_add_app_05.png](https://qiita-image-store.s3.amazonaws.com/0/109065/1e49df71-d1b0-f937-e848-e1c697a8219b.png "Firebase_add_app_05.png")
（見た感じアプリの削除って操作がないんだけど、追加したアプリを削除するのってどうやるのかな…？）


### Android Studioのバージョンを確認
[Android Studio 2.2 Preより前のバージョンではInstant Runとの互換性がない](https://firebase.google.com/docs/android/setup)とのことなので、今回は2.2Preを入れてます。2.2PreでなくてもInstant Runを無効化すればおｋです。
（Instant Runとの互換性がないだけならそんなに気にしなくても良い気もするけど…APKBuildしてadb installすりゃ確認できるんでしょ？）

[Android Studio Project Site](http://tools.android.com/download/studio/builds/android-studio-2-2-preview-1)から対象環境のファイルをDLして入れましょう。
![Firebase_studio2.2pre.png](https://qiita-image-store.s3.amazonaws.com/0/109065/4b6b008b-f9f6-be0c-bf48-2c644983c8ce.png "Firebase_studio2.2pre.png")
（元々入ってるStudioとは別で動くので安心ですね）



## Firebase Analytics導入
なにはともあれまずはAnalyticsを導入してみます。
Firebase Documentationの[Get Started with Firebase Analytics for Android](https://firebase.google.com/docs/analytics/android/start/)を参考にサンプルアプリに組み込みましょう。

導入はとてもシンプルで、appのbuild.gradleに1行追加して、

```app/build.gradle
compile 'com.google.firebase:firebase-analytics:9.0.0'
```

アプリ起動時に実行される処理でFirebaseAnalyticsインスタンスを初期化してやるだけです。
（Applicationを継承してonCreateでやる場合はマニフェストへの追記も忘れずに…）

```MyApplication
// Obtain the FirebaseAnalytics instance.
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
```


以上でAnalyticsにデータが上がってくるはずですが、せっかくなのでイベントログも仕込んでみます。
最初に起動されるActivityのonCreate()に以下を追記します。

```MainActivity
Bundle fireLogBundle = new Bundle();
fireLogBundle.putString("TEST", "FireSample app MainActivity.onCreate() is called.");
MyApplication.getFirebaseAnalytics().logEvent(FirebaseAnalytics.Event.APP_OPEN, fireLogBundle);
```

[FirebaseAnalytics.Event](https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics.Event#constant-summary)として25種類の定義値が用意されており、それだけでもかなりのユースケースをフォローできそうです。もちろん独自のEventを設定してもOK。

「24時間以内に最初のレポートが表示されます」とあるので、まぁお茶でも飲んでゆっくり待ちましょう。
![Firebase_analytics_01.png](https://qiita-image-store.s3.amazonaws.com/0/109065/26cc4ebf-5d12-0e30-a6b4-978eb7b04ba1.png "Firebase_analytics_01.png")

（追記）大体4時間程度でデータが見れるようになりました。
![Firebase_analytics_02.png](https://qiita-image-store.s3.amazonaws.com/0/109065/27253a36-b457-1ce3-4d0e-f88b0f8a0087.png "Firebase_analytics_02.png")



## Notifications導入
無料で無制限に、しかもAnalyticsのセグメント毎にPush通知（Notification）が送れて開封率なども見れるということで、（個人的には）とても魅力的な機能なので試してみたいと思います。

例のごとくFirebase Documentationの[Send a Notification to a User Segment](https://firebase.google.com/docs/notifications/android/console-audience#set_up_the_sdk)を参考にサンプルアプリに組み込みましょう。

まずはappのbuild.gradleに以下を追記

```app/build.gradle
compile 'com.google.firebase:firebase-messaging:9.0.0'
```

これだけでFirebaseのNotificationコンソールから送れるらしいです！！なんてこった／(^O^)＼

ということで早速Firebaseのナビゲーションから「Notifications」を開き、「最初のメッセージを送信」を押下します。
![Firebase_notif_combine_01.png](https://qiita-image-store.s3.amazonaws.com/0/109065/bd6a9c3d-5db2-a2cc-1bd0-288d5cec5c60.png "Firebase_notif_combine_01.png")

Notificationは時限式にしたりパラメータを付与したりできるみたいですが、まずは最低限の入力で送ってみます。（とはいえ、コンバージョンイベントにはデフォルトで送信済みと開封済みは提供されるようです）
送信されるメッセージの再確認ダイアログが出るので安心感ありますね。
![Firebase_notif_combine_02.png](https://qiita-image-store.s3.amazonaws.com/0/109065/87cf3478-8c51-9452-438b-013e9cbb3e18.png "Firebase_notif_combine_02.png")

送ったメッセージはFirebaseの画面から一覧で確認でき、送信内容から送信ターゲット数、既読数、コンバージョン数（Notification作成時に設定したコンバージョンイベントに到達した数）まで確認できます。
![Firebase_notif_05.png](https://qiita-image-store.s3.amazonaws.com/0/109065/24d9b891-b450-934c-959f-3945a73d491c.png "Firebase_notif_05.png")

ここでNotificationが届かなくてちょっと嵌ったのですが、「アプリがforegroundにいる時にNotificationを表示させるにはFirebaseMessagingServiceを継承したクラスにロジックを書かないといけない」ようです。（Documentに強調して書いてありました。。。）
アプリをbackgroundにしてからNotificationを送付したらちゃんと届きました。
![Firebase_notif_06.png](https://qiita-image-store.s3.amazonaws.com/0/109065/11952695-7eed-c2ae-7056-43222b26eb5e.png "Firebase_notif_06.png")


Notificationは届いたものの、コンソールで確認しても送信数が0件のままだったのですが、おそらく時間が経てば反映されるのでしょう…

[追記]半日くらい放置したら送信数／既読数ともに反映されてました。
![Firebase_notif_07.png](https://qiita-image-store.s3.amazonaws.com/0/109065/5ad6637d-9d72-3fa5-7399-2e6555e3c066.png "Firebase_notif_07.png")


※GCMのときはcollapse_keyとかあった気がするけどFirebaseではなくなってる気がする？

## Crash Reporting導入
アプリで発生したExceptionを見ることのできるCrash Reportingも入れておきましょう。
Firebase Documentationの[Report Crashes](https://firebase.google.com/docs/crash/android)を参考にサンプルアプリに組み込みます。

```app/build.gradle
compile 'com.google.firebase:firebase-crash:9.0.0'
```

これだけで完了です。
試しにExceptionを投げるボタンを付けてExceptionを発生させられるようにしておきましょう。
main_activity.xmlに```"@+id/btn_throw_exception"```というIDでボタンを作っておきます。

```MainActivity#onCreate()
binding.btnThrowException.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        throw new NullPointerException("ｶﾞｯ!!!");
    }
});
```

Exceptionを発生させてログを見てみると、FirebaseCrashSenderServiceImplというクラスでCrash Reportを送付していることが分かります。
![Firebase_crash_01.png](https://qiita-image-store.s3.amazonaws.com/0/109065/b1b4e84a-8fe4-71f6-8b9a-494f194fb7be.png "Firebase_crash_01.png")

コンソールからCrashReportingを見るとエラーの発生数や影響したユーザー数、クラスタ数が見れます。
「クラスタとは、類似するスタック トレースを持つエラーのグループです。以下の表の行はクラスタを表します。」らしいです。
![Firebase_crash_02.png](https://qiita-image-store.s3.amazonaws.com/0/109065/98a5c065-8a70-818b-da0d-eca01591c129.png "Firebase_crash_02.png")

さらにエラー毎の詳細画面ではスタックトレースやエラー発生時の端末の状態も見ることができます。
![Firebase_crash_03.png](https://qiita-image-store.s3.amazonaws.com/0/109065/20490bb5-840a-4897-c328-8a2f6cd31f85.png "Firebase_crash_03.png")


# まとめ
AnalyticsとNotifications、CrashReportingを導入してみて、とにかくシンプルで簡単に機能を使うことが出来ました。
特にいままではGCMでサーバーへのリクエストからアプリでの実装まで、とにかく大変だったPush通知でのNotification表示がアプリ側の実装なしで出来たのは思わず小躍りしたくなるほどでした！！
反対にAnalyticsとCrashReportingはGoogle AnalyticsとCrashlyticsからすぐに乗り換えるほどではない印象ですね。

こんな便利なサービスが無料で使えるなんてGoogleさんありがとう！！！

今回導入した機能以外にも、SNS連携のsign upやリアルタイムDBを使ったチャット機能など、Webアプリも含めた機能が簡単に作れそうなので引き続きいじっていきたいです。