Firebaseの CloudMessaging での通知実装と Apple Developer Certificates に苦戦したメモ

基本的にはこちらの手順に従う方針だが、既にCertificateを作成していたり、本番用と開発用で違ったり、Bundle ID が違うと動かないなどがあり苦戦したのでメモ。
https://qiita.com/ausssxi/items/89305cdb3935d6f6f2b8

全体的に、iOSにおけるプッシュ通知は基本UserNotificationsをimportして使うが、そもそものプッシュ通知を送るバックエンド側のシステムが必要で、それがニフクラモバイルやFirebaseで実装されることが多いっぽい。なおFirebaseのCloud MessagingというのはFirebaseコンソールからユーザーにメルマガみたいにプッシュ通知を送れる仕組みのことっぽい。

##主なつまずきポイント

###シミュレータでは通知こないっぽい？
まずiOSにおける通知はアプリ起動中はこない模様。`Singing & Capabilities`で`Push Notifications`と合わせて`Backgound Modes`を追加しているので、アプリが表で起動してないときに通知を送る仕様なのだが、Xcodeで起動させるiPhoneシミュレータではそもそもバックグランドモードが使えないらしい。
![スクリーンショット 2021-01-23 14.47.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/3da9a0b5-03fb-4694-5d6f-a218780fe4f5.png)



###FirebaseのCloud Messagingで通知を行うためのCertificateも必要
通知で使うAPNs証明書(.p12ファイル）を作成するために Apple Push Services というCertificate（.cerファイル）を作成する必要がある。Certificate=証明書=.cerファイル=.p12ファイルであり、Firebaseなどの外部で証明書を使う際にはこの.12形式に変換してやらないといけないようだ。

####最新のAPNsキー方式ではうまくいかなかった
Firebase公式が推奨しているAPNsキー（.p8ファイル）の方式では機能しなかった。もしかすると Bundle ID が一致してなかったときに試したからかもしれない。試していないがわかりやすそうなQiitaを見つけたので貼っておく。
https://qiita.com/MYamate_jp/items/994a31d5408bc09998bc

![スクリーンショット 2021-01-23 14.36.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/657b8764-7377-2027-79d9-a72d7e415327.png)


###Bundle ID が Firebase とアプリで同じでないといけない
同じプロジェクトでもBundle ID を変えてしまえばApp Store Connectでは別アプリとして認識されリリースできる。Firebaseも2つのアプリでデータを共用することができる。しかしFirebaseへのアプリ登録時のBundle ID と異なるアプリへは、Cloud Messaging を用いたプッシュ通知が送れないっぽい。
![スクリーンショット 2021-01-23 14.37.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/01549de5-388e-be60-e87b-b68b0ea51ba1.png)


###実機テストではDevelopmentだが本番ではDistribution
初めに提示したQiitaは実機で通知テストするためにDevelopmentのCertificateを作成していたが、（Xcode11がiOS14に対応しておらず、Xcode12にあげるためにBigSurにあげるのは嫌だったので）本番環境で使うDistributionのCertificateを使って通知のテストをした。幸い、まだ通知機能を実装しているアプリはリリースされていないのでTestflightでインストールしたテスターにしか通知はいかない。

なお本番環境用のAPNsのCertificateは`Sandbox & Production`の方。
![スクリーンショット 2021-01-23 12.16.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/da0d0cbc-7681-34c8-d01d-c6a2595c614a.png)


##Apple Developer Certificates

###そもそもの知識
CSR、鍵、証明書、Provisioning Profile については以下の図解がとても分かりやすい。
https://qiita.com/fujisan3/items/d037e3c40a0acc46f618

Certificateは使用しているMacが変わらない限りは1つだけ作って、それをもとにProvisioningProfileを作成すればいいはず。

CertificateにはiOS DistributionとApple Distributionの2つがあるが、基本Xcode11以降を使っている場合はシステムが自動生成するCertificateも後者になるので、後者を使うとよいみたい。
https://qiita.com/warapuri/items/2a32cb2201ce75aa5f4b

####超ざっくりした理解
・DevelopmentとDistributionで2つのCertificate Typeがある
・Developmentは実機テストで使い、DistributionはApp Storeへの配信に使う
・Provisioning Profileに書かれたMac・デバイス・App・機能の組み合わせでないとビルドが許可されていない

手元の実機iPhoneにアプリをインストールするのも、App Storeにアプリをリリースするのも、FirebaseのCloud Messagingで通知を送るのも、全部「わたしはAppleに認証されたMac（開発者）,iPhoneですよー」という証明をしないといけない。

証明書やそれを生成するための鍵（CSR生成時に作られる？）はMacの中に保存するが、「どの証明書（TEAM）・App ID・デバイス・機能（Capabilities）で実行できるアプリなのか」というプロファイルを書いたProvisioning Profileというものをアプリに持たせ、それをApp Storeに申請することで、App Store Connect側は「あ、はいはい、確かに認証されたMac（TEAM）、App ID、機能の組み合わせねー」としてビルドとして認めてくれるようだ。

なおデバイスについては、あくまでDevelopmentのCertificateで実機テストするためのデバイスのことだと思われ、本番用のDistributionのCertificateを使ってリリース作業を行う場合は特に関係ないと思われる。ただ実機テストをする際に実機に Provisioning Profile がインストールされるそうである。


###XcodeのCertificateが消えない問題
直接的には関係ないが、Certificateを作り直したりしていると遭遇。Keychainの証明書や鍵（認証局に証明書を要求するためのCSRと一緒に作られる？）を削除して、ProvisioningProfileを削除しても消えない。右クリックでDeleteしようとしてもダメ出し、Untitledとなっている証明書は存在せず、また日付から特定しようとしてもそれらしきものはない。
![スクリーンショット 2021-01-23 14.28.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/95e8e263-5954-fe5a-784d-28942f8b5b70.png)

Apple Development Certificate の「〇〇の Macbook Pro」と、それに対応する Provisioning Profileは UITest のアプリが勝手に生成するようなので削除しても復活するらしい。誰か助けて。