Firebase Cloud Messaging Notification не отправляет формат полезной нагрузки iOS

Вчера вечером я тестировал push-уведомление, используя FCM в своих приложениях, и он разбился (он работал несколько дней назад). Я тестирую его, используя меню уведомлений в консоли firebase.

Далее я изучал формат полезной информации уведомления и не включал формат iOS, такой как формат Apple Documentation.

Я повторно проверяю свой сертификат APNs, и разработка не прошла, я пытаюсь повторно загрузить сертификат, и он получил аналогичную ошибку как этот.

Я представил обратную связь команде firebase и сказал, что это проблема в конце. (Примечание: я также отправляю ответ команды firebase по ссылке выше). Мой Dev APNs Certificate вернулся, но формат все тот же.

Здесь полезная нагрузка, которую я получил (из функции Swift Print)

{
    "collapse_key" = "com.xxx.xxx";
    from = xxx;
    notification =     {
        badge = 3;
        body = "Firebase console";
        e = 1;
        title = Test;
    };
}

И эта полезная нагрузка сделает iOS не отображать push-уведомление.

И на основе эта документация FCM для iOS

следующий код заставит приложение разбиться при получении уведомления

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)
}
  • Я уже пытаюсь повторно загрузить мой сертификат APN, но все же ошибка
  • Я также отправлю еще одну обратную связь, но команда Firebase не ответит на нее.

Я что-то пропустил?

Edit:

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

В частности, эта строка приведет к сбою приложения, и я подозреваю, что это связано с изменением формата полезной нагрузки (отсутствует полезная нагрузка aps).

print("Message ID: \(userInfo["gcm.message_id"]!)")

Код работает хорошо, когда удаляет его (и создает выше), но все же я не получаю формат полезной нагрузки aps, поэтому уведомление никогда не будет появляться, когда приложения будут в фоновом режиме. Также мой обработчик уведомлений не будет работать, когда приложения на переднем плане.

Изменить 2:

Я уже регистрирую уведомление в своем AppDelegate

let setting = UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge] , categories: nil)
    application.registerUserNotificationSettings(setting)
    application.registerForRemoteNotifications()

Я знаю об этом и уже включил фоновый режим Push Notification и Remote Notification.

Возможности

Редактировать 28 июня 2016 года:

Я попытался снова нажать уведомление из консоли firebase, и все же я получил тот же формат полезной нагрузки, что и этот

%@ [notification: {
    badge = 2;
    body = "Test Message";
    e = 1;
    sound = default;
    sound2 = default;
    title = Test;
}, collapse_key: com.xxx, from: 717xxxxxx]

Моя настройка Firebase консоли FCM выглядит так:

Настройка консоли Firebase

Редактировать 8 июля 2016 года:

Это мой код AppDelegate

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {

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

        // Firebase 
        let setting = UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge] , categories: nil)
        application.registerUserNotificationSettings(setting)
        application.registerForRemoteNotifications()

        FIRApp.configure()

        print(FIRInstanceID.instanceID().token())

        FIRAnalytics.logEventWithName(kFIREventAppOpen, parameters: nil)

        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(tokenRefreshNotificaiton), name: kFIRInstanceIDTokenRefreshNotification, object: nil)

        return true
    }

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

    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
        // 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)

        var body = ""
        var title = "20Fit"

        guard let aps = userInfo["aps"] as? [String : AnyObject] else {
            print("Error parsing aps")
            return
        }

        if let alert = aps["alert"] as? String {
            body = alert
        } else if let alert = aps["alert"] as? [String : String] {
            body = alert["body"]!
            title = alert["title"]!
        }

        let banner = Banner(title: title, subtitle: body, image: nil, backgroundColor: UIColor.blackColor(), didTapBlock: nil)
        banner.show(duration: 5.0)
    }

    func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
           FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: .Sandbox)
    }

    func tokenRefreshNotificaiton(notification: NSNotification) {
        let refreshedToken = FIRInstanceID.instanceID().token()!
        print("InstanceID token: \(refreshedToken)")

        sendTokenToServer()

        // Connect to FCM since connection may have failed when attempted before having a token.
        connectToFcm()
    }

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

    func applicationDidEnterBackground(application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
        FIRMessaging.messaging().disconnect()
        print("Disconnected from FCM")
    }

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

    func applicationDidBecomeActive(application: UIApplication) {
        connectToFcm()
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
        FIRAnalytics.logEventWithName("app_terminated", parameters: nil)
    }


}

Вот полный журнал из моих приложений

2016-07-08 19:26:48.022 20FIT Member[2525:1122556] WARNING: Firebase Analytics App Delegate Proxy is disabled. To log deep link campaigns manually, call the methods in FIRAnalytics+AppDelegate.h.
2016-07-08 19:26:48.273 20FIT Member[2525:1122556] Configuring the default app.
2016-07-08 19:26:48.318 20FIT Member[2525:] <FIRAnalytics/DEBUG> Debug mode is on
2016-07-08 19:26:48.338 20FIT Member[2525:] <FIRAnalytics/INFO> Firebase Analytics v.3200000 started
2016-07-08 19:26:48.338 20FIT Member[2525:] <FIRAnalytics/INFO> To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see google link)
2016-07-08 19:26:48.343: <FIRInstanceID/WARNING> Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(null)"
2016-07-08 19:26:48.350: <FIRMessaging/INFO> FIRMessaging library version 1.1.0
2016-07-08 19:26:48.339 20FIT Member[2525:] <FIRAnalytics/DEBUG> Debug logging enabled
2016-07-08 19:26:48.365 20FIT Member[2525:] <FIRAnalytics/DEBUG> Uploading data. Host: https://play.googleapis.com/log
2016-07-08 19:26:48.366 20FIT Member[2525:] <FIRAnalytics/DEBUG> Firebase Analytics is monitoring the network status
Optional("cXwsIWfiJas:APA91bGjUnL-oztH9LntO4EaKdJxPQN_-Za5ydC-hPR-_HPZXNm4m_mzqSztvbBG7HczNN5Jr7Btr8h4ETF5FyOOUn8Ombk4c3RoTL6GDFrh6BnG0ECs_r_Hqx1dnVHeJVwLQo4JInn2")
2016-07-08 19:26:48.406 20FIT Member[2525:] <FIRAnalytics/DEBUG> Successfully parsed a configuration. Version: 1464617411301000
2016-07-08 19:26:48.429 20FIT Member[2525:] <FIRAnalytics/DEBUG> Firebase Analytics is ready to receive events
2016-07-08 19:26:48.432 20FIT Member[2525:] <FIRAnalytics/DEBUG> No network. Upload task will not be scheduled
2016-07-08 19:26:48.434 20FIT Member[2525:] <FIRAnalytics/DEBUG> Cancelling background upload task.
2016-07-08 19:26:48.437 20FIT Member[2525:] <FIRAnalytics/DEBUG> Scheduling user engagement timer
2016-07-08 19:26:48.438 20FIT Member[2525:] <FIRAnalytics/DEBUG> Timer scheduled to fire in approx. (s): 3600
2016-07-08 19:26:48.441 20FIT Member[2525:] <FIRAnalytics/INFO> Firebase Analytics enabled
2016-07-08 19:26:48.445 20FIT Member[2525:] <FIRAnalytics/DEBUG> Logging event: origin, name, params: app, app_open, {
        "_o" = app;
    }
2016-07-08 19:26:48.477 20FIT Member[2525:] <FIRAnalytics/DEBUG> Scheduling user engagement timer
2016-07-08 19:26:48.478 20FIT Member[2525:] <FIRAnalytics/DEBUG> Canceling active timer
2016-07-08 19:26:48.479 20FIT Member[2525:] <FIRAnalytics/DEBUG> Timer scheduled to fire in approx. (s): 3600
2016-07-08 19:26:48.562 20FIT Member[2525:] <FIRAnalytics/DEBUG> Network status has changed. code, status: 2, Connected
2016-07-08 19:26:48.566 20FIT Member[2525:] <FIRAnalytics/DEBUG> Network status has changed. code, status: 2, Connected
2016-07-08 19:26:48.618 20FIT Member[2525:] <FIRAnalytics/DEBUG> Event logged. Event name, event params: app_open, {
        "_o" = app;
    }
2016-07-08 19:26:48.635 20FIT Member[2525:] <FIRAnalytics/DEBUG> Timer scheduled to fire in approx. (s): 3143.319384038448
2016-07-08 19:26:48.636 20FIT Member[2525:] <FIRAnalytics/DEBUG> Upload task scheduled to be executed in approx. (s): 3143.319384038448
2016-07-08 19:26:48.637 20FIT Member[2525:] <FIRAnalytics/DEBUG> Do not schedule an upload task. Task already exists
2016-07-08 19:26:48.710 20FIT Member[2525:] <FIRAnalytics/DEBUG> Received SSL challenge for host. Host: https://play.googleapis.com/log
2016-07-08 19:26:49.408 20FIT Member[2525:] <FIRAnalytics/DEBUG> Uploading data. Host: https://play.googleapis.com/log
Connected to FCM.
2016-07-08 19:26:49.869 20FIT Member[2525:] <FIRAnalytics/DEBUG> Received SSL challenge for host. Host: https://play.googleapis.com/log
2016-07-08 19:26:50.206 20FIT Member[2525:] <FIRAnalytics/DEBUG> Uploading data. Host: https://play.googleapis.com/log
2016-07-08 19:26:50.723 20FIT Member[2525:] <FIRAnalytics/DEBUG> Received SSL challenge for host. Host: https://play.googleapis.com/log
%@ [notification: {
    badge = 2;
    body = "Test Message";
    e = 1;
    sound = default;
    sound2 = default;
    title = Yoiii;
}, collapse_key: com.xxx.xxx, from: 717xxxx]
Error parsing aps

Ответ 1

У меня была та же проблема

Относительно этой части направляющих fcm: https://firebase.google.com/docs/cloud-messaging/ios/client#swizzling_disabled_receive_messages_through_the_messaging_apns_interface

Я решил проблему с добавлением setAPNSToken:type:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    [[FIRInstanceID instanceID] setAPNSToken:deviceToken type:FIRInstanceIDAPNSTokenTypeSandbox];
}

После этого fcm начал отправлять push файлы с корректно отформатированной информацией для iOS.

Ofcourse для производства enviromnent FIRInstanceIDAPNSTokenTypeProd

Ответ 2

"Полезная нагрузка", которую вы печатаете, выглядит правильно для меня. Однако обратите внимание, что это не полезная нагрузка APN. Это фактически словарь пользовательской информации. Если я понимаю ваш вопрос, вы, кажется, беспокоитесь о том, что поле "aps" отсутствует. Вы не увидите это поле в словаре пользовательской информации.

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

Попробуйте отправить локальное уведомление (расписайте его на 30 секунд):

localNotif.fireDate = [[NSDate date] dateByAddingTimeInterval:30];

И нажмите домашний ключ и подождите.

Ответ 3

"Полезная нагрузка", которую вы предоставили, была (предположительно) произведена последней строкой метода didReceiveRemoteNotification, т.е. print("%@", userInfo).

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

Я думаю, что что-то еще сбой вашего приложения. Вы заглянули в системный журнал? (Если вы используете симулятор, откройте "Отладка" > "Открыть системный журнал" ).

Я бы предложил запустить демонстрационное приложение Firebase (pod try Firebase), чтобы убедить себя, что он работает так, как вы ожидали.

Ответ 4

Я смотрю, почему ваш gcm.message_id имеет значение null, дайте мне пару дней.

Чтобы не получать уведомление, когда приложение находится в фоновом режиме, убедитесь, что вы зарегистрировались для удаленных уведомлений, как показано в примере с быстрым стартом (см. didFinishLaunchingWithOptions) здесь: https://github.com/firebase/quickstart-ios/blob/master/messaging/FCMSwift/AppDelegate.swift

Кроме того, убедитесь, что в Xcode вы установили свои возможности, позволяющие обрабатывать фоновые уведомления.

Ответ 5

Такая же проблема. Кроме того, Firebase messsage с ключом "aps", кажется, не доставляется при отправке с консоли. Должны быть некоторые ошибки с Firebase для изменения формата полезной нагрузки.

О получении уведомления Firebase в фоновом режиме, в этом случае я думаю, что iOS не будет распознавать формат полезной нагрузки → вообще не уведомлять. Чтобы прочитать сообщение из Firebase на фоне, не переходите в режим FIRMessaging.messaging(). Disconnect() при переходе в фоновый режим. Затем вы должны получить свое сообщение и обработать его собственным дескриптором (все еще нет системного уведомления).

Ответ 6

Я прошел через форум разработчиков Apple и кажется, что didRegisterForRemoteNotificationsWithDeviceToken не работал в режиме SandBox и работал только в Production. didRegisterForRemoteNotificationsWithDeviceToken Здесь я регистрирую deviceToken с помощью firebase. Поскольку этого не происходило, Firebase отправлял полезную нагрузку с помощью клавиши notification, поскольку он не знал, что устройство было Apple. Сегодня Apple исправила проблему, и теперь я могу отправлять уведомления.

Ответ 7

У меня была такая же проблема, я добавил приоритет "высокий", и это сработало для меня!

{
    "collapse_key" :"com.xxx.xxx",
    to: "xxx",
    priority : "high",
    notification :{..}
}