web-dev-qa-db-ja.com

FCMトークンを持つデバイスへのFirebase通知は送信されたが受信されなかった

FCMトークンを使用して、Firebase通知コンソールから特定のデバイスに単純なプッシュ通知を送信しようとしています。 firebase通知コンソールには、送信された通知が表示されますが、デバイスは通知を受信しません。通知を送信してから、コンソールがdidReceiveRemoteNotificationからログを記録するかどうかを確認しようとしましたが、(優先度をhighに設定した場合でも)通知がFirebaseコンソールで送信されたように表示されるのに時間がかかりすぎます。

App Delegate

import UIKit
import Firebase
import FirebaseStorage
import FirebaseDatabase
import FirebaseMessaging
import CoreData
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        // Use Firebase library to configure APIs
        FirebaseApp.configure()

        /////
        // For Firebase Cloud Messaging (FCM)
        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()
        // End of [for Firebase Cloud Messaging (FCM)]
        /////

        return true
    }

    ///////////////////////
    // FCM Setup

    // Monitor token generation for FCM: Be notified whenever the FCM token is updated
    func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
        print("Firebase registration token: \(fcmToken)")
    }

    // Monitor token generation for FCM:
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
    }    // Handle messages received through the FCM APNs interface
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
        print("didReceiveRemoteNotification")
        // If you are receiving a notification message while your app is in the background,
        // this callback will not be fired till the user taps on the notification launching the application.
        // TODO: Handle data of notification

        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)

        // Print message ID.
        // gcm_message_id
        if let messageID = userInfo["gcmMessageIDKey"] {
            print("Message ID: \(messageID)")
        }

^私の推測では、問題は「gcm_message_id」/「gcmMessageId」/「gcm.message_id」に関係している可能性があります。これは、以下で試した3つのアプローチのそれぞれで異なるためです

        // Print full message.
        print(userInfo)
    }

    // Handle messages received through the FCM APNs interface
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("didReceiveRemoteNotification (withCompletionHandeler)")
        // If you are receiving a notification message while your app is in the background,
        // this callback will not be fired till the user taps on the notification launching the application.
        // TODO: Handle data of notification

        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)

        // Print message ID.
        if let messageID = userInfo["gcmMessageIDKey"] {
            print("Message ID: \(messageID)")
        }

^私の推測では、問題は「gcm_message_id」/「gcmMessageId」/「gcm.message_id」に関係している可能性があります。これは、以下で試した3つのアプローチのそれぞれで異なるためです

        // Print full message.
        print(userInfo)

        completionHandler(UIBackgroundFetchResult.newData)
    }

    // End of [FCM Setup]
    ///////////////////////
}

View Controller

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Retrieve the current registration token for Firebase Cloud Messaging (FCM)
        let token = Messaging.messaging().fcmToken
        print("FCM token: \(token ?? "")")
      }
}

資格とプッシュ通知の有効化

プッシュ資格を追加しました see here およびプッシュ通知の有効なバックグラウンドモード see here とGoogleService-Info.plistをプロジェクトに追加しました。

通知の送信方法

Firebase Notificationsコンソールから通知を作成しています(以下を参照)。通知自体の構造に問題はないはずです。 enter image description here

この問題を解決するために次の方法を試しましたが、すべて同じ結果が得られました。

通知がFirebase Notification Consoleで送信済みとしてマークされているのにデバイスに表示されない理由を誰かが知っていますか?

7
Rbar

プッシュ通知を操作するときに使用するトラブルシューティングの手順は次のとおりです。

  1. 最初にFirebaseサービスから独立してプッシュを動作させます。私はこれを使う tool。
  2. バンドル識別子の名前空間の衝突がないことを確認してください。したがって、たとえば、デバイス上でのアプリのビルド、testflightビルド、および/または開発ビルドの任意の組み合わせがあります。アプリの1つのインスタンスを除くすべてを削除します。バンドル識別子は、プッシュ通知のルーティング先のアプリをデバイスが認識する方法です。
  3. 他のすべてが失敗した場合-私は新しいサンプルプロジェクトをビルドして問題を特定し、それを新しいfirebaseプロジェクトに接続して、他のビジネスロジックを使用せずにプッシュを機能させるだけにフォーカスを絞れるかどうかを確認しますアプリ。これは、私が正気になっていないことを自分に証明するのに役立ち、それが私の悩みの原因となっている不思議なネットワーク状態ではないことを私に証明します。

私はこれがあなたがそれをすべて理解するのに役立つあなたの仕事に役立つことを願っています。

5
Doug

DidRegisterForRemoteNotificationsWithDeviceToken funcに次のコードを追加してみてください。

Messaging.messaging().apnsToken = deviceToken

したがって、次のようになります。

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    Messaging.messaging().apnsToken = deviceToken
}

私の仕事です。

1
Luthfi Rahman

通知がFirebase Notification Consoleで送信済みとしてマークされているのに、デバイスに表示されない理由を誰かが知っていますか?

「送信済み」は「受信済み」を意味しないため。

デバイスでの通知の受信は保証されません。基本的なAPNSインフラストラクチャでは、デバイスで通知が受信または処理された場合でも情報を取得できません。

デバイスで正常に送信されたメッセージを受信できない場合は、多くの理由が考えられます。さらに、Firebaseトークンを受け取ったとしても、デバイスが通知を受け取ることができるというわけではありません。

問題を特定するために、最小限のセットアップを構築し、FirebaseなしでAPNSを使用することをお勧めします。ターミナルまたはNWPusher( https://github.com/noodlewerk/NWPusher )を使用して、ローカルのmacOSシステムから通知を送信し、iOSネイティブのリモートプッシュ通知フレームワークを使用して通知を受信できます。

APNSデバイストークンを通知の送信に必要な正しい形式に変換するように注意してください。

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    let token = deviceToken.hexEncodedString()
    print("Token: \(token)")
}

データ拡張:

extension Data {
    func hexEncodedString() -> String {
        return map { String(format: "%02hhx", $0) }.joined()
    }
}
0
jn-se

プロジェクトのCapabilitiesですべてを実行したようです。

いくつかのポイント:

  • 次のように、クラスをmessaging delegateに準拠させます。

    Messaging.messaging().delegate = self
    
  • 証明書を適切に設定し、すべてをFirebaseのプッシュ通知構成にアップロードしたことを確認してください(正確な用語ではありません)。

  • Firebase Push Notification Serviceを使用するいくつかのアプリケーションを実行しました。サンプルアプリケーションを最初から作成すると、何が間違っているのかを理解するのに役立つ場合があります。

そして...プッシュ通知用にアプリケーションを登録するためのより良いコードブロックがあります。

    // Setup Push Notifications

    if #available(iOS 10.0, *) {
        let center  = UNUserNotificationCenter.current()
        center.delegate = self
        center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
            if error == nil{
                DispatchQueue.main.async(execute: {
                    application.registerForRemoteNotifications()
                })
            }
        }
    }
    else {
        let notificationTypes: UIUserNotificationType = [.sound, .alert, .badge]
        let notificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil)
        application.registerForRemoteNotifications()
        application.registerUserNotificationSettings(notificationSettings)
    }
0
Glenn