FirebaseでPUSH通知を行った時の覚書（Android）

# やりたいこと
AndroidでFCM（Firebase Cloud Messaging）を使って、PUSH通知を受信できるようにする。
参画した案件の開発で純正FCMの実装を初めて行ったので、その覚書。

#### やったこと
- Firebaseの導入
- FCMの導入(PUSH通知を受信するロジックの実装)

# Firebaseの導入
[Firebase全般の概要](https://firebase.google.com/docs?hl=ja) を見て、プロジェクトを作成

メモ1: プロジェクトを作る時の設定値
<img width="1440" alt="スクリーンショット 2019-05-03 22.18.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384422/6a312c94-2b81-7f20-8eb0-050e663f4a9b.png">

メモ2: SHA1の取得方法
AndroidStudioを使う場合、コマンドを打たなくてもTaskがすでに用意されているので、
キャプチャにあるsigningReportを実行するとSHA1などを取得できます。
<img width="1250" alt="スクリーンショット 2019-05-05 0.58.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384422/d49cc48a-0370-56b8-515b-722bcd2855c3.png">
<img width="1440" alt="スクリーンショット 2019-05-03 22.27.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384422/9d6b42c7-a082-00cb-4858-6cc0d78e4f0e.png">

# FCMの導入(PUSH通知を受信するロジックの実装)

[ガイド](https://firebase.google.com/docs/cloud-messaging) を読むと、AndroidManifestの設定やServiceの実装についてわかります。
わからない部分やソースの全体像を確認したい場合は、サンプルが用意されています。
https://github.com/firebase/quickstart-android/tree/master/messaging

#### わからなかった、使わなかった部分

[Google Play 開発者サービスのチェック](https://firebase.google.com/docs/cloud-messaging/android/client#sample-play)
使わなかったですが、理解を深めようとした時にこちらの記事が参考なりました。
GoogleMapなどを未使用だったので、チェックは未実装にしましたが、やっておいた方がよかったのかも。

[AndroidアプリでGoogle Play Serviceの使用可否を検証する](https://qiita.com/outerlet/items/e2603a08cf9bb9716fc0)

[自動初期化を禁止する](https://firebase.google.com/docs/cloud-messaging/android/client#prevent-auto-init)

**2020/3/11 追記**
自動初期化の禁止は許諾をとってからFirebaseを使いたい場合などに使用するが、
通常使うことはなさそう。
（通知しなければいいだけなので）
以下、サイトを参考
- https://developers-jp.googleblog.com/2017/04/take-control-of-your-firebase-init-on.html
- https://developers-jp.googleblog.com/2017/04/take-control-of-your-firebase-init-on.html

#### ベストプラクティスを知りたい部分
```
/**
 * Called if InstanceID token is updated. This may occur if the security of
 * the previous token had been compromised. Note that this is called when the InstanceID token
 * is initially generated so this is where you would retrieve the token.
 */
override fun onNewToken(token: String?) {
    Log.d(TAG, "Refreshed token: $token")

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // Instance ID token to your app server.
    sendRegistrationToServer(token)
}
```
サンプルコードの sendRegistrationToServer で 該当するユーザーやグループにのみメッセージを送ったりするためにTokenをアプリケーションサーバに送るのですが、このタイミングで通信が失敗した場合はどこでリカバリするべきなのか？今回はアプリ起動時にリカバリ処理(インスタンスIDの再送信)を入れましたが、ベストプラクティスがあれば教えていただきたいです。。

# PUSH通知を受信する
https://firebase.google.com/docs/cloud-messaging/android/receive
データの処理自体は前述のサンプルにもコードがのっているので、それほど難しくないように思えます。
[メッセージの処理](https://firebase.google.com/docs/cloud-messaging/android/receive#handling_messages) にある表のパターンを読んで、
それぞれのパターンごとに挙動を理解することが大事だと思います。

# 今回できなかったこと
サンプルベースの開発だったため、トピック、デバイスグループを使用しませんでした。
実際は配信の目的やテストを考慮するとデバイスグループも使用するべきですし、
そもそもFirebaseコンソールを使って都度手動の送信を行うのではなく、
サーバ側のアプリケーションも準備しておいた方が良いと思いました。

# まとめ
覚書として、あとでやった時に忘れている・困りそうな部分を中心にメモしましたが、
Firebase自体は内容も大きいのでやっぱり細かい部分を忘れていたり（実装内容というより何でそうしたか）、
コードや参考URLを丁寧にまとめようとすると時間がかかりすぎるので、こまめにまとめようと思いました。。