web-dev-qa-db-fra.com

Notification Firebase au périphérique avec le jeton FCM dit Envoyé mais pas reçu

Je tente d'envoyer une notification Push simple à partir de la console de notification firebase à un périphérique spécifique à l'aide d'un jeton FCM. La console de notification de Firebase indique que la notification a été envoyée, mais que le périphérique ne la reçoit pas. J'ai essayé d'envoyer la notification et d'attendre de voir si la console se connecte à partir de didReceiveRemoteNotification, mais la notification prend trop de temps (plusieurs heures) pour être affichée comme étant envoyée dans la console Firebase (même lorsque j'ai défini la priorité sur high).

Délégué App

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)")
        }

^ Je suppose que le problème peut avoir à voir avec "gcm_message_id"/"gcmMessageId"/"gcm.message_id" car il est différent dans chacune des trois approches ci-dessous}

        // 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)")
        }

^ Je suppose que le problème peut avoir à voir avec "gcm_message_id"/"gcmMessageId"/"gcm.message_id" car il est différent dans chacune des trois approches ci-dessous}

        // Print full message.
        print(userInfo)

        completionHandler(UIBackgroundFetchResult.newData)
    }

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

Contrôleur de vue

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 ?? "")")
      }
}

Droits et activation des notifications push

J'ai ajouté les droits d'accès Push  see here et modes de fond activés pour les notifications Push  see here et a ajouté GoogleService-Info.plist à mon projet.

Méthode d'envoi de la notification

Je crée une notification à partir de la console de notifications Firebase (comme indiqué ci-dessous). La structure de la notification elle-même ne devrait donc pas poser de problème .  enter image description here

J'ai essayé les approches suivantes pour remédier au problème, mais toutes ont abouti au même résultat:

Est-ce que quelqu'un sait pourquoi la notification est marquée comme envoyée dans la console de notification de Firebase mais n'apparaît pas sur le périphérique?

5
Rbar

Voici quelques étapes de dépannage que j'utilise lorsque je travaille avec des notifications Push:

  1. Commencez par faire fonctionner Push Push indépendamment des services de Firebase. J'utilise cet outil.
  2. Assurez-vous de ne pas avoir de collisions d’espace de noms d’identificateurs d’ensemble. Ainsi, par exemple, toute combinaison de génération d'appstore, de testflight et/ou de développement d'une application sur le périphérique. Supprimer toutes les instances de l'application sauf une. L'identificateur de paquet indique comment votre appareil sait à quelle application router la notification Push. 
  3. Lorsque tout échoue, j'essaie d'isoler le problème en construisant un nouvel exemple de projet et en l'associant à un nouveau projet de base de feu, afin de voir si je peux me concentrer uniquement sur la possibilité de faire fonctionner Push sans autre logique métier dans mon environnement. app. Cela m'aide à prouver à moi-même que je ne suis pas devenu fou et à prouver que ce n'est pas une condition de réseau mystérieuse menant à mes malheurs.

J'espère que cela vous aidera pendant que vous travaillez à tout comprendre.

5
Doug

Essayez d'ajouter le code suivant à didRegisterForRemoteNotificationsWithDeviceToken func:

Messaging.messaging().apnsToken = deviceToken

Donc ça va ressembler à ça:

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

    Messaging.messaging().apnsToken = deviceToken
}

C'est un travail pour moi.

1
Luthfi Rahman

Quelqu'un sait-il pourquoi la notification est marquée comme envoyée dans la console de notification de Firebase mais n'apparaît pas sur le périphérique?

Parce que "envoyé" ne signifie pas "reçu".

La réception des notifications sur l'appareil ne peut pas être garantie. Avec l'infrastructure APNS de base, vous ne pouvez même pas obtenir les informations si une notification a été reçue ou traitée sur le périphérique.

Si vous ne recevez pas un message envoyé avec succès sur l'appareil, les raisons peuvent être multiples. De plus, même si vous recevez un jeton Firebase, cela ne signifie pas que votre appareil peut recevoir la notification dans tous les cas.

Pour isoler le problème, je suggérerais de construire la configuration minimale et d’utiliser APNS sans Firebase. Vous pouvez utiliser Terminal ou NWPusher ( https://github.com/noodlewerk/NWPusher ) pour envoyer des notifications à partir de votre système macOS local et du cadre de notifications Push à distance natif iOS pour recevoir des notifications.

Veillez à convertir le jeton de périphérique APNS au format correct requis pour l'envoi d'une notification:

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

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

Extension de données:

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

Je vois que vous avez tout fait dans la variable Capabilities de votre projet.

Des points:

  • Conformez votre classe à messaging delegate comme ceci:

    Messaging.messaging().delegate = self
    
  • Assurez-vous que vous avez correctement configuré vos certificats et transféré tout le contenu dans les configurations de notification push de Firebase (terme non exact).

  • J'ai utilisé plusieurs applications qui utilisent le service de notification push de Firebase et créer un exemple d'application à partir de zéro peut vous aider à comprendre ce que vous avez fait de mal.

Et ... voici un bloc de code plus agréable pour enregistrer votre application pour la notification Push.

    // 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