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

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

Ответ 1

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

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


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

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

Ответ 2

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

Messaging.messaging().apnsToken = deviceToken

FirebaseInstanceID 2.0.8, FirebaseMessaging 2.0.8

Ответ 3

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

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

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

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

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

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

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

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

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

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

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

    1. удалите уведомление → приложение НЕ обрабатывается приложением

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

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

В этом случае, если пользователь не открывает приложение, нажав на уведомление, нет способа получить данные уведомления.

Чтобы быть независимым от состояния приложения, вам необходимо настроить сервер, на котором вы можете запросить конкретные данные. Например. у вас есть представление, которое показывает все уведомления, вам нужен API для запроса конкретных данных. Не следует обрабатывать данные в методе получения Pushnotification.

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

Ответ 4

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

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

Ответ 5

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

  1. откройте Project Navigator> AppCapabilities> Background Mode> проверить наличие удаленных уведомлений

  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. Удачного кодирования

Ответ 6

AFAIK, для ios вы не сможете использовать FCM для отправки push-уведомлений для приложений в фоновом режиме или в убитом состоянии.

Уведомление PushBase Firebase