PUROGU LADESU

ポエムがメインのブログです。

【Swift】Push Notification / Firebase Cloud Messaging

通知を受信できるように設定する

Set up a Firebase Cloud Messaging client app on iOS

Identifierの設定

設定にてCapabilitiesのPushNotificationにチェックを入れる。

Certificateの作成

Apple Push Notification service SSL (Sandbox) を選択。
IdentifiersでPushNotificationを有効にしたAppIDを選択する。

FirebaseCloudMessagingに証明書を渡す

Certificatesで作成した証明書をローカルにダウンロードする。
Macのキーチェーンアクセスアプリでp12形式でエクスポートして保存。
Firebaseコンソールのプロジェクトの設定画面より、APNs 証明書のアップロード。

通知を許可

Xcodeの方のCapabilityでPushNotificationとRemoteNotificationを有効にする。

通知を許可するリクエストを出すコードを追加
if #available(iOS 10.0, *) {
    // For iOS 10 display notification (sent via APNS)
    UNUserNotificationCenter.current().delegate = self

    let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
    UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: {_, _ in })
} else {
    let settings: UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
    application.registerUserNotificationSettings(settings)
}

application.registerForRemoteNotifications()
通知のテスト送信

FirebaseコンソールのCloud Messagingの画面からアプリを指定すれば届くはず。

Send messages with the Firebase console

その他

受け取った通知のハンドリング

通知から起動した際そのままだとアプリがフォアグラウンドになるだけなので、挙動をハンドリングする。

Receive messages in an iOS app  |  Firebase

extension AppDelegate: UNUserNotificationCenterDelegate {
    // 通知の受け取り
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

        let userInfo = response.notification.request.content.userInfo

        if let messageID = userInfo["gcm.message_id"] {
            print("Message ID: \(messageID)")
        }

        print(userInfo)

        completionHandler()
    }
    
}
FCMトークンの扱い

アプリの起動時に個別の端末を識別するFCMトークンが生成されるらしい。
端末宛に送信する場合などはサーバに保存して利用するとのこと。

extension AppDelegate: MessagingDelegate {
    
    // トークンの変更をモニタリング(必要なら適宜サーバに保存する)
    // 起動時にも毎回呼ばれる
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        print("Firebase registration token: \(String(describing: fcmToken))")

        let dataDict: [String: String] = ["token": fcmToken ?? ""]
        NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
        
        // TODO: If necessary send token to application server.
        // Note: This callback is fired at each app startup and whenever a new token is generated.
    }
 
}

サーバから特定のデバイスにメッセージを送信する

Build app server send requests  |  Firebase

REST Resource: projects.messages  |  Firebase

Firebase Admin SDKを使うか、RESTでJSONをPOSTします。
その際登録済みのデバイストークンとメッセージを指定します。

FirebaseならCloudFunctionのトリガーで通知する感じがいいのかな。