簡體   English   中英

Firebase 雲消息通知不發送 iOS 有效負載格式

[英]Firebase Cloud Messaging Notification not sending iOS payload format

昨晚我在我的應用程序中使用 FCM 測試推送通知,但它崩潰了(幾天前它正在工作)。 我使用 firebase 控制台中的通知菜單對其進行了測試。

我進一步調查了通知有效負載格式已更改,並且不包括Apple 文檔中的 iOS 格式。

我重新檢查了我的 APNs 證書,但開發證書不見了,我嘗試重新上傳證書,但出現了類似這樣的錯誤。

我向 firebase 團隊提交了一份反饋,並說這是他們最終的問題。 (注意:我還在上面的鏈接中發布了 firebase 團隊的回復)。 我的 Dev APNs 證書又回來了,但格式還是一樣。

這是我得到的有效載荷(來自 Swift Print 函數)

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

而這個payload使得iOS不會顯示推送通知。

並基於此適用於 iOS 的 FCM 文檔

以下代碼將使應用程序在通知到來時崩潰

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)
}
  • 我已經嘗試重新上傳我的 Dev APNs 證書,但仍然出錯
  • 我還提交了另一個反饋,但 Firebase 團隊尚未回復

我錯過了什么嗎?

編輯:

就像我上面說的,幾天前它可以工作,當這個問題出現時它會崩潰。

特別是這一行會使應用程序崩潰,我懷疑這是因為有效載荷格式發生了變化(缺少 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()

我知道這一點並且已經啟用推送通知和遠程通知后台模式。

能力

2016 年 6 月 28 日編輯

我再次嘗試從 firebase 控制台推送通知,但我仍然得到了相同的有效負載格式

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

我的 FCM Firebase 控制台設置如下所示

Firebase 控制台設置

2016 年 7 月 8 日編輯

這是我的 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

我有同樣的問題

關於 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 開始發送帶有為 iOS 正確格式化的有效負載的推送。

當然對於生產環境使用FIRInstanceIDAPNSTokenTypeProd

您正在打印的“有效負載”在我看來是正確的。 但是,請注意,這不是 APN 負載 它實際上是一個用戶信息字典。 如果我理解您的問題,您似乎擔心缺少"aps"字段。 您不會在用戶信息字典中看到該字段。

您是在真實設備上還是在模擬器中運行它? 請記住,模擬器無法顯示遠程通知,在真實設備上,應用程序需要在后台顯示通知。

嘗試發送本地通知(安排 30 秒時間):

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

然后按home鍵等待。

您提供的“有效負載”(大概)是由didReceiveRemoteNotification方法的最后一行生成的,即print("%@", userInfo)

您聲稱上面的代碼使應用程序崩潰,這與成功打印到日志的代碼相矛盾。

我認為是其他原因導致您的應用程序崩潰。 你看系統日志了嗎? (如果您正在使用模擬器,請轉到調試>打開系統日志)。

我建議運行 Firebase 演示應用程序( pod try Firebase ),以說服自己它按預期工作。

我正在調查為什么你的 gcm.message_id 為空,給我幾天時間。

為了在應用程序處於后台時未收到通知,請確保按照此處的快速入門示例(請參閱 didFinishLaunchingWithOptions)中所示注冊遠程通知: https : //github.com/firebase/quickstart-ios/blob/master /messaging/FCMSwift/AppDelegate.swift

此外,請確保在 Xcode 中您已將功能設置為允許處理后台通知。

同樣的問題在這里。 此外,在使用控制台發送時,帶有鍵“aps”的 Firebase 消息似乎無法傳遞。 必須是 Firebase 的一些錯誤才能更改有效負載格式。

關於在后台模式下獲取 Firebase 通知,在這種情況下,我認為 iOS 將無法識別有效負載格式 -> 根本沒有通知。 要在后台讀取來自 Firebase 的消息,請不要在切換到后台模式時調用FIRMessaging.messaging().disconnect() 然后你應該得到你的消息並通過你自己的句柄處理它(仍然沒有系統通知)。

我瀏覽了 Apple 的開發者論壇,似乎didRegisterForRemoteNotificationsWithDeviceToken不能在 SandBox 模式下工作,只能在生產中工作。 didRegisterForRemoteNotificationsWithDeviceToken是我向 firebase 注冊didRegisterForRemoteNotificationsWithDeviceToken的地方。 由於沒有發生這種情況,Firebase 發送帶有notification密鑰的有效負載,因為它不知道設備是 Apple。 今天蘋果解決了這個問題,現在我可以發送通知了。

我遇到了同樣的問題,我添加了“高”優先級,它對我有用!

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

切換您的 wifi/移動數據即可解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM