React Nativeとプッシュ通知 (iOS編)
前回の記事でAndroidに対応したので、今回はiOSの対応を行なっていきます。
iOSのセットアップ
Xcode上でプロジェクトの設定を変更したいので
最初に、前回にも設定したようにBundle Identifierが com.example.rn-push-notification.ios
となっていることを確認します。
さらに通知を受信するためにCapabilityの中からBackground Modes
と Push Notifications
を追加しておきます。
また証明書もまだであれば設定しておきましょう。
Firebaseプロジェクトの設定
FirebaseコンソールでプロジェクトにiOSアプリを追加します。 ここで先ほど設定していたバンドルIDを指定しておきます。
続けてGoogleService-Info.plistをダウンロードしておき、残りの作業はスキップして大丈夫です。
そして次にプロジェクトにプッシュ通知を送るためのAPNs 認証キーを設定します。
まず証明書を作成するためにApple Developerへ行き、新たなKeyを作成してApple Push Notifications service (APNs)
を有効にします。
Keyをダウンロードし、画面に表示されているTeam IDとKey IDをメモしておきます。
Firebaseプロジェクトの設定からクラウドメッセージングに入ります。
先ほど作成したKeyの情報を設定します。
Firebaseの初期化
Xcodeの作業に戻ります。(ここの作業はドキュメントに沿っています)
もし前回実行していなければ下記コマンドでPodsを更新します。
cd ios/ && pod install
そして先ほどダウンロードしたGoogleService-Info.plistをプロジェクトに追加します。
Firebaseを初期化するコードを追加します。 AppDelegate.mを開き、ファイル先頭付近に下記コードを追加し、
#import <Firebase.h>
同じファイルのdidFinishLaunchingWithOptions
メソッドの中に下記コードを追加します。
if ([FIRApp defaultApp] == nil) { [FIRApp configure]; }
プッシュ通知の受信を許可
React Nativeの世界に戻ります。 iOSでは予め通知を受信する許可を得る必要があるため、その処理を追加します。
App.tsxを開き下記のようにコードを編集します
const App = () => { ... // 通知の許可をリクエストする async function requestUserPermission() { const authStatus = await messaging().requestPermission(); const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL; if (enabled) { console.log('通知が許可されました'); } } useEffect(() => { // 最初に通知の許可をリクエストする requestUserPermission(); ... }, []); ... };
ここまででプッシュ通知を受信する最低限の準備ができました。
プッシュ通知を送信
iOSシミュレータでは通知を受信できないので、Xcodeから実機でアプリを実行します。
最初に通知許可のダイアログが表示されるので許可し、アプリをバックグラウンドに入れます。
前回と同様にFirebaseコンソールから通知を送信します。
しかし、通知は受信できるかと思いますがAndroidで表示されてたような画像が表示されていないことがわかります。
iOSでは通知に画像を表示するにはNotification Service Extensionを実装する必要があります。 (ドキュメント: Modifying Content in Newly Delivered Notifications )
Notification Service Extension
Notification Service Extension実装方法なのですが、React Nativeであっても特別なことはなさそうで、通常のネイティブ実装と同じ方法で実装することになるようです。つまり、
実装についてはReact Nativeとも関係なく一般的なものになり、長くなってしまうので省略します。 (詳細はこちらのドキュメント)
また、この場合の通知の送信方法も変わります。
プッシュ通知を受信した時にNotification Service Extensionを起動するためには、通知のペイロードに “mutable-content” : 1
を含める必要があります。 (上記のドキュメント参照)
そしてFirebaseコンソールからはこの設定が現在ではできないようです。
従って別の方法でプッシュ通知を送ります。
ここではレガシーなFCM HTTP APIを使って通知を送ってみます。 このAPIは手軽に使えて便利なのですが、実際にはよりセキュアなHTTP v1 APIを利用するのが良さそうです。
まず、APIの実行に必要なサーバーキーと送信者IDをFirebaseコンソールのSettings > クラウドメッセージングから確認します。
curl -X POST -H "Authorization: key=ここにサーバーキー" -H "project_id: key=ここに送信者ID" -H "Content-Type: application/json" -d '{ "to": "/topics/weather", "notification": { "title": "通知テスト", "body": "Hello world", "image": "https://picsum.photos/id/1015/300/200" }, "mutable_content": true, "data": { "imageURL": "https://picsum.photos/id/1015/300/200" } }' https://fcm.googleapis.com/fcm/send
mutable_content
を設定しておき、data.imageURL
の画像をNotification Service Extensionで表示させます。
これで画像が表示されるはずです。
以上です。
まとめ
今回この辺を調べたのはReact NativeでiOSのApp Extension(Notification Service Extensionなど)を実装するのはどうやるんだろう?との疑問が発端でした。結局それは一般的なネイティブ実装でやるっぽく、ちょっと残念でした。。。JS/TSで書ければ良かったな。
コードはここに置いておきます。 github.com