Firebase Cloud Messaging iOS: нет фонового push-уведомления

Использование новых облачных сообщений Firebase с помощью swizzling метода. Я успешно получаю полезную нагрузку в методе didReceiveRemoteNotification в своем делете приложения, когда мое приложение находится на переднем плане. Однако я не получаю никакой полезной нагрузки, а didReceiveRemoteNotification не вызывается, когда мое приложение связано с фоном, несмотря на ответ api, что сообщение успешно отправлено (см. Ниже)
Вот запрос, который я отправляю в FCM api для запуска push-уведомления 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"  
 } 
}


с ответом FCM

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

Вот мой код appDelegate

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

}

Я вызываю этот код при более позднем потоке в своем приложении, чтобы запросить разрешения

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

Так как я могу получать уведомления, когда приложение находится на переднем плане, я предполагаю, что это устранит все опасения, что мои сертификаты apns не загружены или что регистрационный токен неверен. Если это не так, прокомментируйте, и я снова спустится в эту кроличью яму. Там, вероятно, что-то простое, что я упускаю из виду, но как я могу получить уведомления, появляющиеся во время работы приложения? Благодаря

4b9b3361

По-видимому, (несмотря на использование метода swizzling, который должен делать это автоматически), вы все равно должны установить токен APNS в экземпляре Firebase. Следовательно, это означает, что вы также должны реализовать метод didRegisterForRemoteNOtificationsWithDeviceToken с чем-то вроде

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


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

Как добавленное примечание. Использование "priority":"high" было полезно для тестирования, поскольку оно сразу отправило уведомление.

10
20 июля '16 в 7:29
источник

Требуемое поведение, по крайней мере для моего приложения, заключается в получении push-уведомления, где содержимое PN (Push-уведомления) должно отображаться на нужной странице приложения.

У меня есть три разных состояния приложения, куда может прийти PN: (конечно, это зависит от вашей реализации, но вы должны понять, как Apple обрабатывает PN в этих состояниях)

(поведение определяется яблоком!)

1) приложение находится на переднем плане:

  • PN получил
  • всплывает в Центре уведомлений (вы можете щелкнуть по нему или нет - это не имеет значения)
  • значок будет обновлен
  • PN доступен на нужной странице

В этом случае приложение всегда обрабатывает PN

2) приложение в фоновом режиме:

  • PN получил
  • всплывает в Центре уведомлений (вы можете щелкнуть по нему или нет - это не имеет значения)
  • значок будет обновлен
  • PN доступен на нужной странице

В этом случае приложение всегда обрабатывает PN

3) приложение убито/закрыто:

  • PN получил
  • всплывает в Центре уведомлений
  • сейчас есть три возможных пути

    1. уведомление салфетки прочь → PN будет не обрабатывается приложением

    2. откройте приложение через иконку программы запуска непосредственно → PN будет не обрабатывается приложением

    3. нажмите на уведомление → PN будет обработано приложением

Конечно, это зависит от вашей реализации, потому что в случае "3. Откройте приложение с помощью значка запуска" вы можете просто получить все PN в приложении запуска через дополнительный API. НО вы должны понять, как Apple предотвращает обработку PN в некоторых случаях.

Я надеюсь, что это помогает кому-то!

0
19 февр. '19 в 9:19
источник

Выполните следующие действия после получения успешного токена от FCM, чтобы включить выборку данных полезной нагрузки в фоновом режиме с помощью FCM:

  1. откройте Навигатор проекта> AppCapabilities> Режимы фона> проверить наличие удаленных уведомлений

  2. В App.delegate определить:

    func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    
        print("userinfo in background mode on-\(userInfo)")
    
        completionHandler(UIBackgroundFetchResult.newData)
    }
    
  3. Правильно отформатируйте данные в соответствии с рекомендациями Apple: введите описание ссылки здесь

  4. Не забудьте добавить пару ключ-значение: {"content-available":1} если вы не сможете получить полезную нагрузку в фоновом режиме.

Теперь попробуйте отправить уведомление снова, используя токен FCM. Удачного кодирования

0
11 мая '18 в 13:53
источник

Сходным образом с решением Дэниела Джорджа я мог бы исправить свою проблему:

Messaging.messaging().apnsToken = deviceToken

FirebaseInstanceID 2.0.8, FirebaseMessaging 2.0.8

0
14 февр. '18 в 17:42
источник

Убедитесь, что вы добавили "content_available": true в полезной нагрузке JSON. В противном случае вы не получите push-уведомление в фоновом режиме.

"notification" : {
            "content_available" : true,
            "body" : "this is body",
            "title" : "this is title"
}
0
23 окт. '17 в 12:41
источник