wake-up-neo.com

Firebase Cloud Messaging iOS: Keine Push-Benachrichtigung im Hintergrund

Mit dem neueren Firebase-Cloud-Messaging mit der Methode swizzling kann ich erfolgreich eine Nutzlast in der didReceiveRemoteNotification-Methode in meinem App-Delegaten empfangen, wenn meine App vordergrundig ist. Ich bekomme jedoch keine Art von Nutzlast und didReceiveRemoteNotification wird nicht aufgerufen, wenn meine App backgrounded ist, trotz der Antwort der API, dass die Nachricht erfolgreich gesendet wurde (siehe unten)
Hier ist die Anforderung, die ich an die FCM-API sendet, um eine Push-Benachrichtigung auszulösen. https://fcm.googleapis.com/fcm/send

{
"to": "{valid-registration-token}",
"priority":"high", //others suggested setting priority to high would fix, but did not
  "notification":{
      "body":"Body3",
      "title":"test"  
 } 
}


mit Antwort von FCM

{
      "multicast_id": 6616533575211076304,
      "success": 1,
      "failure": 0,
      "canonical_ids": 0,
      "results": [
        {
          "message_id": "0:1468906545447775%a4aa0efda4aa0efd"
        }
      ]
    }

Hier ist mein appDelegate-Code

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        Fabric.with([Crashlytics.self])
        FIRApp.configure()

        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.tokenRefreshNotification),
                                                         name: kFIRInstanceIDTokenRefreshNotification, object: nil)
        return true
    }



    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
        // Let FCM know about the message for analytics etc.
        FIRMessaging.messaging().appDidReceiveMessage(userInfo)

        // Print full message.
        print("%@", userInfo)

        // handle your message

//        let localNotification = UILocalNotification()
//        localNotification.fireDate = NSDate()
//        let notification = userInfo["notification"]!
//        localNotification.alertBody = notification["body"] as? String
//        localNotification.alertTitle = notification["title"] as? String
//        localNotification.timeZone = NSTimeZone()
//        application.scheduleLocalNotification(localNotification)

    }

    func tokenRefreshNotification(notification: NSNotification) {
        let refreshedToken = FIRInstanceID.instanceID().token()!
        print("InstanceID token: \(refreshedToken)")
        LoginVC.registerForPushNotifications()
        connectToFcm()
    }


    //foreground messages
    func applicationDidBecomeActive(application: UIApplication) {
        connectToFcm()
    }

    // [START disconnect_from_fcm]
    func applicationDidEnterBackground(application: UIApplication) {
        FIRMessaging.messaging().disconnect()
        print("Disconnected from FCM.")
    }


    func connectToFcm() {
        FIRMessaging.messaging().connectWithCompletion { (error) in
            if (error != nil) {
                print("Unable to connect with FCM. \(error)")
            } else {
                print("Connected to FCM.")
            }
        }
    }

}

Ich rufe diesen Code zu einem späteren Zeitpunkt in meiner App auf, um nach Berechtigungen zu fragen

static func registerForPushNotifications() {
    let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
            UIApplication.sharedApplication().registerUserNotificationSettings(settings)
            UIApplication.sharedApplication().registerForRemoteNotifications()
}

Da ich in der Lage bin, Benachrichtigungen zu erhalten, während die App im Vordergrund steht, gehe ich davon aus, dass dadurch alle Bedenken beseitigt werden, dass meine Apns-Zertifikate nicht hochgeladen werden oder dass das Registrierungstoken falsch ist. Wenn dies nicht der Fall ist, kommentieren Sie bitte, und ich werde dieses Kaninchenloch wieder hinuntergehen ... Es gibt wahrscheinlich etwas einfaches, das ich übersehe, aber wie kann ich die Benachrichtigungen erhalten, während die App im Hintergrund ist? Vielen Dank

15
Daniel George

Anscheinend müssen Sie (trotz der Methode swizzling, die dies automatisch tun sollte) das APNS-Token auf der Firebase-Instanz festlegen. Folglich müssen Sie die Methode didRegisterForRemoteNOtificationsWithDeviceToken auch mit etwas implementieren

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {


        // set firebase apns token
        FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Unknown)
}

Als zusätzliche Anmerkung. Die Verwendung von "priority":"high" war für Tests hilfreich, da die Benachrichtigung sofort gesendet wurde.

10
Daniel George

Befolgen Sie diese Schritte, nachdem Sie ein erfolgreiches Token von FCM erhalten haben, um den Abruf der Hintergrundnutzdaten mithilfe von FCM zu aktivieren:

  1. Öffnen Sie Project Navigator> AppCapabilities> Hintergrundmodi> Suchen Sie nach Remote-Benachrichtigungen

  2. In App.delegate definieren Sie:

    func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    
        print("userinfo in background mode on-\(userInfo)")
    
        completionHandler(UIBackgroundFetchResult.newData)
    }
    
  3. Formatieren Sie Ihre Nutzdaten korrekt gemäß den Apple-Richtlinien: Geben Sie die Linkbeschreibung hier ein

  4. Vergessen Sie nicht, das Schlüsselwertpaar hinzuzufügen: {"content-available":1} , Es sei denn, Sie können keine Nutzdaten im Hintergrund abrufen.

versuchen Sie jetzt, die Benachrichtigung erneut mit dem FCM-Token zu senden. Hab eine glückliche Kodierung

0
Vinayak Pal

Stellen Sie sicher, dass Sie "content_available": true in der JSON-Payload hinzugefügt haben. Andernfalls erhalten Sie keine Push-Benachrichtigung im Hintergrundmodus.

"notification" : {
            "content_available" : true,
            "body" : "this is body",
            "title" : "this is title"
}
0
Rupom

Ähnlich wie bei Daniel Georges Lösung könnte ich mein Problem beheben mit:

Messaging.messaging().apnsToken = deviceToken

FirebaseInstanceID 2.0.8, FirebaseMessaging 2.0.8

0
Colibri

Das gewünschte Verhalten, zumindest für meine App, gilt für das Eintreffen einer Push-Benachrichtigung, bei der der Inhalt der PN (Push-Benachrichtigung) auf einer gewünschten Seite in der App angezeigt werden soll.

Ich habe drei verschiedene App-Zustände, in denen ein PN ankommen kann: .__ (natürlich hängt es von Ihrer Implementierung ab, aber Sie sollten eine Vorstellung davon bekommen, wie Apple das PN in diesen Zuständen verarbeitet).

(das Verhalten wird von Apple bestimmt!)

1) Die App steht im Vordergrund:

  • PN erhalten
  • erscheint im Benachrichtigungscenter (Sie können entweder darauf klicken oder nicht - es spielt keine Rolle)
  • abzeichen werden aktualisiert 
  • PN ist auf der gewünschten Seite verfügbar

In diesem Fall verarbeitet die App Always / die PN

2) Die App befindet sich im Hintergrund:

  • PN erhalten
  • erscheint im Benachrichtigungscenter (Sie können entweder darauf klicken oder nicht - es spielt keine Rolle)
  • abzeichen werden aktualisiert
  • PN ist auf der gewünschten Seite verfügbar

In diesem Fall verarbeitet die App Always / die PN

3) Die App wird beendet/geschlossen:

  • PN erhalten
  • erscheint im Benachrichtigungscenter 
  • jetzt gibt es drei möglichkeiten

    1. wischbenachrichtigung weg -> PN wird von der AppNICHTverarbeitet

    2. Öffnen Sie die App über das Startsymbol direkt -> PN wirdNICHTvon der App verarbeitet

    3. klicken Sie auf die Benachrichtigung -> PN wird von der App verarbeitet

Dies hängt natürlich von Ihrer Implementierung ab, denn für den Fall "3. Öffnen Sie die App direkt über das Startsymbol" können Sie einfach alle PN auf dem App-Start über eine zusätzliche API abrufen. ABER Sie sollten wissen, wie Apple die PN-Verarbeitung in einigen Fällen verhindert.

Ich hoffe das hilft jemandem!