Firebase赤ちゃんがKotlinでPUSH通知を送信するまで

はじめまして。プロ赤ちゃんです。
この記事では、FirebaseのFも理解できていない赤ちゃんが三日三晩苦しんだ末にFirebase赤ちゃんからFirebase幼稚園に入園するまでのサクセスストーリーを書いていきます。
よろしくおねがいします

# Firebase赤ちゃんの誕生（サイトアクセス～ログインまで）

[Firebaseのサイト](https://console.firebase.google.com/)にアクセスし、押してくれと言わんばかりの「使ってみる」ボタンを押します。
Googleアカウントのログイン画面が出てくるのでログインするかアカウントを作るかして先に進みます。
そうしたら↓の画面が出てきました！Firebase赤ちゃんの誕生です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/424de5a6-b5f3-7f4c-d1ed-8b2359a44f3d.png)

次はプロジェクトを作成します。

# Firebase乳児期（プロジェクト作成まで）

さっきの画面で出てきた、「プロジェクトを作成」ボタンを押してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/d6956c96-df4a-a563-55ff-278b140062bc.png)
プロジェクトが何か分からないまま、いきなり名前をつけてと言われました。赤ちゃんはプロジェクトがなんなのか分からないので名前を付けるわけにもいかず泣いてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/4012897e-957f-949d-beb3-4eb5bbbbcd3f.png)
どうやら、プロジェクトとは幼稚園のクラスのようなものらしいです。
同じクラスのお友達は同じ絵本やおもちゃが使えるように、同じパッケージの中にあるアプリは同じ機能が使えるみたいです。
これがあればAndroidとiOSでバラバラにアプリを作ったり、あとから作ったアプリにユーザー情報の引き継ぎが出来たりしそうですね！
赤ちゃんはAndroid専門なので、iOS専門の赤ちゃんがいれば一緒のプロジェクトを使って両OSの対応が出来そうです！

プロジェクトについて理解できたので、先に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/05e0de96-60fe-5c88-7956-a17f7f258c23.png)
今回はちゃんとしたプロジェクトではないので適当に付けました。
プロジェクト名は自分以外の赤ちゃんやお兄さんお姉さんが見て、何のアプリのプロジェクトか簡単に分かる名前がついているといいですね。

「続行」ボタンを押すと、↓の画面に進みました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/33accf0c-6911-fb5b-c19d-5c7c264c8e71.png)
またわけわかんないことがいっぱい書いてあってぐずりそうです。
PUSH通知に必要な「Cloud Messaging」がこの中にいるのが見えました。ほかにも色々と大事そうな機能が見えるので、有効にして「続行」を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/96344344-bf15-1d66-3e71-2521fa78fae5.png)
ゴールが見えてきました！
アナリティクスの地域を選択します。最初は「アメリカ合衆国」が選択されているので、プロジェクトのターゲットとなる国を選択します。
赤ちゃんは「日本」を選びました。海外をターゲットにしているプロジェクトでない限り、自国を選択でいいと思います。
Googleアナリティクス関連の規約にすべて同意できたら、いよいよ「プロジェクトを作成」ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/4edbe075-a6bb-8d8e-9d0b-21873e6b38dd.png)
待機画面でしばらく待っていたら、プロジェクトが準備できたみたいです！
早速「続行」ボタンを押してプロジェクトを確認しに行きましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/a79e219d-0f3e-232b-9d34-adb22372184e.png)
プロジェクト画面です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/0664574c-e316-ea41-fa4c-5dfa2a23e048.png)
Firebaseのトップ画面（コンソール）にも、しっかりプロジェクトが存在していますね！

次はいよいよアプリケーションを連携していきます

# Firebase幼児期（Androidアプリケーションを追加する）

赤ちゃんは失敗を重ねて成長するものです。
つまり、Firebase赤ちゃんはアプリケーション連携で失敗しました。

### 大前提
連携するアプリを用意しておきます。
ない場合は適当に作っておいてください。起動できる状態なら何でも構わないので、新規作成した直後ので大丈夫です。
赤ちゃんは乳児期に作成したFirebaseプロジェクト名に合わせて「ExampleAndroidApp」というアプリケーションを用意しました。

### Firebase連携失敗例その1

まずFirebaseのサイト側から進めました。
プロジェクト画面のドロイド君（Androidのアイコン）をクリックして、↓の画面に進みました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/2b759bf4-a531-a1a6-d963-1053cf31716e.png)
Androidパッケージ名には用意したアプリのパッケージ名を設定します。Activityの一番上に書いてあるヤツです。com.から入れます。
アプリのニックネームはつけてもつけなくてもOKです。アプリ名が長かったり、複数登録する場合にすぐわかる状態にしておきたい人はつけておくのをオススメします。
赤ちゃんはこのプロジェクトにこれしか登録しないので省略しました。
最後にデバッグ用の署名証明書を要求されました。
赤ちゃんはこれが分かりませんでした。わからなかったのでスキップしました。
その結果連携が正しくできませんでした。

### Firebase連携失敗例その2

赤ちゃんは前回の失敗から、署名証明書を取得しなかったことが原因だと思いました。
署名証明書を取得するにはkeytoolが必要らしいです。
赤ちゃんの環境ではkeytoolがなかったので、オラクルアカウントを作ってjavaをインストールし、AndroidStudioのターミナルからkeytoolの置かれたディレクトリに移動して

```
keytool -list -v \
-alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore
```
を実行します。パスワードを要求されますが、初期パスワード`android`で通ります。
参考：https://developers.google.com/android/guides/client-auth

これでいける！と赤ちゃんは信じ切っていましたが、これでも連携できませんでした。
ここでついに「Firebase側から連携できないのでは？」という考えに至りました。

## 赤ちゃんでもAndroidStudioからFirebaseにアプリを連携できるのか

結論としては、AndroidStudio側から簡単に設定できました。

AndroidStudioの上のほうにある「tools」から「Firebase」を選択します。
すると、画面右側にアシスタントタブが現れました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/81569fd2-a487-dc3a-b323-8e5185604f48.png)
※赤ちゃんは英語がわからないので日本語化プラグインを入れています
今回使うのは「Cloud Messaging」なので、タブを開いて、「Set up Firebase Cloud Messaging」を押します。

### ①アプリとFirebaseを連携
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/296e302d-1c80-ddb6-8c5e-5a14095d9fe1.png)
①Connect your app to Firebaseから、「Connect to Firebase」を押すと、ブラウザのFirebaseコンソール画面が立ち上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/ba12d934-1e80-31bd-df06-e9a138164852.png)
アプリを連携したいプロジェクトを選んでね！と書いてあるので、先ほど作ったexampleProjectを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/802239cc-d9d3-b72d-68fa-13e9ca62128f.png)
連携できました！さっきまでいっぱい泣いてたのは何だったんでしょうか。「接続」ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/7d476202-8242-6b5e-a815-f026faa97803.png)
真っ白い画面に英語でちょっとちびっちゃいました。多分AndroidStudioに戻ってね～みたいなことが書いてある気がするので、おむつを替えながらAndroidStudioに戻ります。ブラウザは閉じちゃってOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/67ef1a2e-3fe9-25da-aeb8-0d186ddd64b6.png)
①に接続チェックが付いてる！成功です！

### ②FCMを追加
このままの勢いで②Add FCM to your appも追加しちゃいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/91954d9e-c86d-4fea-9fc4-d831c90ad472.png)
こんなダイアログが出てきました。
プロジェクトのbuild.gradle、アプリのbuild.gradleにそれぞれ緑の部分が追加されるみたいですね。
手動でコピペして…ってやる手間が省けてらくちんです！「Accept Changes」を押して、Gradle同期が完了するのを待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/3a269b21-57f0-27ee-88ce-254ad2af8239.png)
無事同期が終われば、こっちにもチェックマークがつきました！完了です！

###### 余談

赤ちゃんは①までの過程で疲れてしまい、②を翌日にしたためアシスタントをど忘れして手動で追加したためにFCMが正しく連携されないという罠に陥って泣いていました。
もし、

```
import com.google.firebase.messaging.FirebaseMessagingService
```
でmessagingが赤くなってFirebaseMessagingService().onNewToken(String)がoverrideできないよ～！という赤ちゃんがいましたら、一度「tools→Firebase→Cloud Messaging→Add FCM to your app」の項目を確認してから再度書き直したりリビルドしたりすると解決するかもしれないです。（今回の記事ではあまり関係のない部分なので、無関係赤ちゃんはこれがimport出来なかったらここまでのどこかで失敗している可能性があるんだな～くらいに思っておいてください）

## Firebase幼児後期（Kotlinで通知を受信して表示させる）
やっと通知に会えます！非常に長い道のりでした。

ちなみに幼児期前期で飛ばしたFirebaseアシスタントの③Access the device registration token以降の項目ですが、もしここも対応してから進みたいんだ！という堅物赤ちゃんがいましたら、ここは非推奨となった[FirebaseInstanceIdService](https://firebase.google.com/docs/reference/android/com/google/firebase/iid/FirebaseInstanceIdService)のトークンを見ているので注意してください。
②までで通知の受信は出来るので今回は対応せずに進めています。
赤ちゃんの環境はAndroidStudio3.6.3なのですが、これって4.xとか新しいバージョンなら更新入ってるんですかね？案件都合とかもあって4系にまだアップデートしてないのでわからないのですが、今までやさしかったAndroidStudioくんに突き放されて大泣きです。ぴえん

### 通知の土台作り

実装内容に関しては[こちらのサイト](https://yyh-gl.github.io/tech-blog/blog/android_push/)を参考にしました。

```AndroidManifest.xml
<!-- applicationタグの中に追加 -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="@string/channel_id"/>

<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_launcher_foreground" />

<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/background" />
```
通知チャンネル、タスクバーに表示される通知アイコン、通知バーの背景色を定義します。
怠惰赤ちゃんなので通知アイコンは元から入っているランチャーアイコンにしました。

```strings.xml
<string name="channel_id">channelId</string>
<string name="channel_name">通知チャンネル名</string>
```
通知チャンネル名はまだ使いませんが、チャンネルIDと一緒に設定しておきます。

```colors.xml
<color name="white">#FFFFFF</color>
<color name="background">@color/white</color>
```

これでバックグラウンド時のみですが通知を受け取る準備が整いました。

## Firebase幼稚園　入学テスト

さて、ここまで来たらやっと送信テストです。
Firebaseコンソールの左端メニューから、「拡大」→「Cloud Messaging」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/61519c5e-b9d7-6fa2-6bad-3213f5e2126c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/30b93221-1e23-4031-81c9-d8422d3865cd.png)
「Send your first message」を押して最初の通知を送ってみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/0c96b540-f5d1-2126-2170-77693dff0ace.png)
送信内容を適当に入力して「次へ」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/b045d7d3-1051-fdd3-4f47-582da8c7357d.png)
ターゲットアプリに通知を送信したいアプリを選んで「次に」
スケジュールは「今すぐ」（初期項目）、コンバージョンイベントは空のままで大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/c2bd363a-39f3-7075-1090-44e6a5ff4e56.png)
最後に、その他のオプションで「Android通知チャンネル」に先ほど設定したchannel_idを設定します。
省略化ですが、Android8以降は通知チャンネルの設定が必須なので、これを設定しないと8以降の端末に通知が届かなくなります。
Androidを使っている大半のユーザーは既に8以上なので、余程古いアプリでもない限り実質必須項目ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/57def3af-6da6-080c-7f4e-deb92a6a0eab.png)
「確認」を押すとこんなダイアログが出てくるので、アプリがバックグラウンドになっていることを確認したら「公開」を押して通知を送信します！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/1e0d4e36-ed0e-9021-a057-44a84cf1da16.png)
Cloud Messagingのトップ画面に送信した通知が表示され、ステータスが完了になってるのを確認している間にスマホの通知が鳴りました！
タスクバーを開くと…
![Screenshot_20201023-235140.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294935/fe91c2e2-6500-b265-9b65-62967e7e6396.png)
通知が届いてます！（Androidのスクショすごいでかくなっちゃった…）
### おめでとう！Firebase幼稚園入園です！

## Firebase赤ちゃんを卒業した感想

今回、訳の分からない部分で詰まることが多く、調べても出てこない内容が多かったので非常に苦しかったです。
連携が終わって通知送信に成功できればあとはわりかしサクサク進みます。（進むとは言っていない）

調べても出てこないといえば何故かPush通知の記事って母数があんまりないらしいんですよね。
Push通知って結構カスタマイズの幅が効くものだし、大体のアプリに実装されているものなのに…

このままだと通知チャンネル名が未設定なので「その他」として表示されたり、アプリがフォアグラウンド時に通知が来なかったり、通知が1件しか溜らなかったり、なんやかんや使い勝手が悪いです。
なのでそれを改善していったり、AndroidのPush通知オプションについて色々と試した記事をFirebase幼稚園卒園論文として次回上げられたらいいな～と思っています！
あとは幼児期前半の最後に余談として挙げた部分の話とかも後続赤ちゃんのために残しておきたいですね（赤ちゃんなので次書く前にpushで苦しんだ記憶を忘れちゃったらごめんなさい）

Qiitaはじめての投稿な上に画像添付祭りになってしまったので、いろんな意味で読みにくい記事になってしまったかと思いますが、ここまで読んでくださりありがとうございました！