FCM Hintergrundbenachrichtigungen funktionieren nicht in iOS

Ich habe ein Problem mit der FCM-Benachrichtigung unter iOS.

Ich erhalte Benachrichtigungen mit Erfolg, wenn sich meine App im Vordergrund befindet (der RückrufdidReceiveRemoteNotification imappdelegate wird ausgelöst), aber ich erhalte keine Benachrichtigungen, wenn sich die App im Hintergrund befindet (in der Benachrichtigungsleiste von iOS wird nichts angezeigt).

Also, ich denke, das Problem liegt im Format der von FCM gesendeten Nachricht. Der von meinem Server an FCM gesendete JSON hat das folgende Format:

{  
   "data":{  
      "title":"mytitle",
      "body":"mybody",
      "url":"myurl"
   },
   "notification":{  
      "title":"mytitle",
      "body":"mybody"
   },
   "to":"/topics/topic"
}

Wie Sie sehen können, gibt es in meinem JSON zwei Blöcke: einen Benachrichtigungsblock (um Benachrichtigungen im Hintergrund zu erhalten) und einen Datenblock (um Benachrichtigungen im Vordergrund zu erhalten).

Ich kann nicht verstehen, warum Benachrichtigungen im Hintergrund nicht empfangen werden. Meine Zweifel betreffen die Reihenfolge der Blöcke (ist es ein Problem, wenn ich den "Daten" -Block vor den "Benachrichtigungs" -Block setze?).

BEARBEITEN Weitere Informationen zum Problem.

Dies ist meine appdelegate.swift:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{
    var window: UIWindow?


    // Application started
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool
    {
        let pushNotificationSettings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
        application.registerUserNotificationSettings(pushNotificationSettings)
        application.registerForRemoteNotifications()

        FIRApp.configure()

        NSNotificationCenter.defaultCenter().addObserver(self, selector: "tokenRefreshNotification:", name: kFIRInstanceIDTokenRefreshNotification, object: nil)

        return true
    }




    // Handle refresh notification token
    func tokenRefreshNotification(notification: NSNotification) {
        let refreshedToken = FIRInstanceID.instanceID().token()
        print("InstanceID token: \(refreshedToken)")

        // Connect to FCM since connection may have failed when attempted before having a token.
        if (refreshedToken != nil)
        {
            connectToFcm()

            FIRMessaging.messaging().subscribeToTopic("/topics/topic")
        }

    }


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


    // Handle notification when the application is in foreground
    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
            // 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

            // Print message ID.
            print("Message ID: \(userInfo["gcm.message_id"])")

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


    // Application will enter in background
    func applicationWillResignActive(application: UIApplication)
    {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }



    // Application entered in background
    func applicationDidEnterBackground(application: UIApplication)
    {
        FIRMessaging.messaging().disconnect()
        print("Disconnected from FCM.")
    }



    // Application will enter in foreground
    func applicationWillEnterForeground(application: UIApplication)
    {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }



    // Application entered in foreground
    func applicationDidBecomeActive(application: UIApplication)
    {
        connectToFcm()

        application.applicationIconBadgeNumber = 0;
    }



    // Application will terminate
    func applicationWillTerminate(application: UIApplication)
    {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


}

Der einzige Weg, wie ich Nachrichten im Vordergrund empfangen kann, ist das Deaktivieren der Swizzling-Methode und das Setzen von FirebaseAppDelegateProxyEnabled auf NO in meiner info.plist.

In diesem Fall besagt die FCM-Dokumentation, dass ich in appdelegate.swift zwei Methoden implementieren muss:

 - FIRMessaging.messaging().appDidReceiveMessage(userInfo)  in didReceiveRemoteNotification callback
 - FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Sandbox) in didRegisterForRemoteNotificationsWithDeviceToken callback

Aber wenn ich diese Funktionen implementiere, kommen keine Nachrichten mehr an, auch wenn sich die App im Vordergrund befindet.

ch weiß, das ist sehr seltsa

EDIT 2:

Wenn die App im Hintergrund ist, wird die Benachrichtigung nicht empfangen, aber wenn ich meine App öffne, wird die gleiche Benachrichtigung sofort empfangen (Methode didReceiveRemoteNotification wird ausgelöst).

Antworten auf die Frage(14)

Ihre Antwort auf die Frage