简体   繁体   English

Firebase 云消息通知不发送 iOS 有效负载格式

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

Last night I test push notification using FCM in my apps and it's crashed (It was working few days back).昨晚我在我的应用程序中使用 FCM 测试推送通知,但它崩溃了(几天前它正在工作)。 I test it using notification menu in firebase console.我使用 firebase 控制台中的通知菜单对其进行了测试。

I further investigate the notification payload format was changed and doesn't include the iOS format like the one in the Apple Documentation .我进一步调查了通知有效负载格式已更改,并且不包括Apple 文档中的 iOS 格式。

I re-check my APNs Certificate and the development one was gone, I try to re-upload the certificate and it got error similar like this one .我重新检查了我的 APNs 证书,但开发证书不见了,我尝试重新上传证书,但出现了类似这样的错误。

I submitted a feedback to firebase team and the said it was an issue in their end.我向 firebase 团队提交了一份反馈,并说这是他们最终的问题。 (Note: I also post the firebase team response in the link above). (注意:我还在上面的链接中发布了 firebase 团队的回复)。 My Dev APNs Certificate is back, but the format the still the same.我的 Dev APNs 证书又回来了,但格式还是一样。

Here's the payload i got (from Swift Print function)这是我得到的有效载荷(来自 Swift Print 函数)

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

And this payload make iOS won't display the push notification.而这个payload使得iOS不会显示推送通知。

And based on this FCM documentation for iOS并基于此适用于 iOS 的 FCM 文档

the following code will make app crashed when notification come以下代码将使应用程序在通知到来时崩溃

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)
}
  • I already try to re-upload my Dev APNs Certificate but still error我已经尝试重新上传我的 Dev APNs 证书,但仍然出错
  • I also submit another feedback but the Firebase Team not reply it yet我还提交了另一个反馈,但 Firebase 团队尚未回复

Am I missing something?我错过了什么吗?

Edit:编辑:

Like I said above, it WAS works few days back, and it become crash when this issue appears.就像我上面说的,几天前它可以工作,当这个问题出现时它会崩溃。

Specifically this line will make the app crash, and I suspect its because the payload format changed (the aps payload missing).特别是这一行会使应用程序崩溃,我怀疑这是因为有效载荷格式发生了变化(缺少 aps 有效载荷)。

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

The code works well when remove it (and produce above), but still I don't get aps payload format so the notification will never pop when the apps in background.该代码在删除它时运行良好(并在上面生成),但我仍然没有获得 aps 有效负载格式,因此当应用程序在后台时通知永远不会弹出。 Also my notification handler will not working when the apps in foreground.当应用程序在前台时,我的通知处理程序也将不起作用。

Edit 2 :编辑2

I already register notification in my AppDelegate我已经在我的 AppDelegate 中注册了通知

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

I'm aware of this and already enabled Push Notification and Remote Notification background mode.我知道这一点并且已经启用推送通知和远程通知后台模式。

能力

Edit 28 June 2016 : 2016 年 6 月 28 日编辑

I tried again pushing notification from firebase console, and still i got the same payload format like this我再次尝试从 firebase 控制台推送通知,但我仍然得到了相同的有效负载格式

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

My FCM Firebase Console Setting looks like this我的 FCM Firebase 控制台设置如下所示

Firebase 控制台设置

Edit 8 July 2016 : 2016 年 7 月 8 日编辑

This is my AppDelegate code这是我的 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)
    }


}

Here is full log from my apps这是我的应用程序的完整日志

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

I had the same problem我有同样的问题

Regarding this part of fcm guides: https://firebase.google.com/docs/cloud-messaging/ios/client#swizzling_disabled_receive_messages_through_the_messaging_apns_interface关于 fcm 指南的这一部分: https ://firebase.google.com/docs/cloud-messaging/ios/client#swizzling_disabled_receive_messages_through_the_messaging_apns_interface

I resolved issue with adding setAPNSToken:type:我解决了添加setAPNSToken:type:

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

After that fcm started sending pushes with payload formatted properly for iOS.在那之后,fcm 开始发送带有为 iOS 正确格式化的有效负载的推送。

Ofcourse for production enviromnent use FIRInstanceIDAPNSTokenTypeProd当然对于生产环境使用FIRInstanceIDAPNSTokenTypeProd

The 'payload' you are printing looks right to me.您正在打印的“有效负载”在我看来是正确的。 However, note that this is not the APN payload .但是,请注意,这不是 APN 负载 It is actually a dictionary of user-info.它实际上是一个用户信息字典。 If I understand your question, you seem to be worried about the "aps" field being missing.如果我理解您的问题,您似乎担心缺少"aps"字段。 You won't see that field in the user-info dictionary.您不会在用户信息字典中看到该字段。

Are you running this on a real device or in the simulator?您是在真实设备上还是在模拟器中运行它? Remember that the simulator can't display remote notifications, and on a real device the app needs to be in the background to show notifications.请记住,模拟器无法显示远程通知,在真实设备上,应用程序需要在后台显示通知。

Try sending a local notification (schedule it for 30 seconds time):尝试发送本地通知(安排 30 秒时间):

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

And press the home key and wait.然后按home键等待。

The 'payload' that you have provided was (presumably) produced by last line of the didReceiveRemoteNotification method, ie print("%@", userInfo) .您提供的“有效负载”(大概)是由didReceiveRemoteNotification方法的最后一行生成的,即print("%@", userInfo)

You claim that the code above makes the app crash, which is in contradiction to that code successfully printing to the log.您声称上面的代码使应用程序崩溃,这与成功打印到日志的代码相矛盾。

I think that something else is crashing your app.我认为是其他原因导致您的应用程序崩溃。 Have you looked in the system log?你看系统日志了吗? (If you are using the simulator, go to Debug>Open System Log). (如果您正在使用模拟器,请转到调试>打开系统日志)。

I would suggest running the Firebase demo app ( pod try Firebase ), to convince yourself that it is working as you would expect.我建议运行 Firebase 演示应用程序( pod try Firebase ),以说服自己它按预期工作。

I'm looking into why your gcm.message_id is null, give me a couple of days.我正在调查为什么你的 gcm.message_id 为空,给我几天时间。

For not getting the notification when the app is in the background, make sure that you register for remote notifications as shown in the quickstart sample (see didFinishLaunchingWithOptions) here: https://github.com/firebase/quickstart-ios/blob/master/messaging/FCMSwift/AppDelegate.swift为了在应用程序处于后台时未收到通知,请确保按照此处的快速入门示例(请参阅 didFinishLaunchingWithOptions)中所示注册远程通知: https : //github.com/firebase/quickstart-ios/blob/master /messaging/FCMSwift/AppDelegate.swift

Also, make sure in Xcode you've set your capabilities to allow for background notifications to be handled.此外,请确保在 Xcode 中您已将功能设置为允许处理后台通知。

Same problem here.同样的问题在这里。 In addition, Firebase messsage with key 'aps' seems not to be delivered while sending with console.此外,在使用控制台发送时,带有键“aps”的 Firebase 消息似乎无法传递。 Must be some bugs with Firebase for changing payload format.必须是 Firebase 的一些错误才能更改有效负载格式。

About getting Firebase notify in background mode, in this case, I think iOS won't recognize the payload format -> no notify at all.关于在后台模式下获取 Firebase 通知,在这种情况下,我认为 iOS 将无法识别有效负载格式 -> 根本没有通知。 To read message from Firebase on background, don't call FIRMessaging.messaging().disconnect() when moving to background mode.要在后台读取来自 Firebase 的消息,请不要在切换到后台模式时调用FIRMessaging.messaging().disconnect() Then you should get your message and handle it by your own handle (still no system notification).然后你应该得到你的消息并通过你自己的句柄处理它(仍然没有系统通知)。

I went through the developers forum of Apple and it seems that didRegisterForRemoteNotificationsWithDeviceToken wasn't working in SandBox mode and worked only in Production.我浏览了 Apple 的开发者论坛,似乎didRegisterForRemoteNotificationsWithDeviceToken不能在 SandBox 模式下工作,只能在生产中工作。 didRegisterForRemoteNotificationsWithDeviceToken is where I register the deviceToken with firebase. didRegisterForRemoteNotificationsWithDeviceToken是我向 firebase 注册didRegisterForRemoteNotificationsWithDeviceToken的地方。 Since that wasn't happening, Firebase was sending payload with notification key as it did not know the device was Apple.由于没有发生这种情况,Firebase 发送带有notification密钥的有效负载,因为它不知道设备是 Apple。 Today Apple fixed the issue and now I am able to send notifications.今天苹果解决了这个问题,现在我可以发送通知了。

I hade the same problem, I added 'high' priority and it worked for me !我遇到了同样的问题,我添加了“高”优先级,它对我有用!

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

切换您的 wifi/移动数据即可解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Firebase 云消息传递未以正确格式为 iOS 通知内容和服务扩展发送 aps 负载 - Firebase Cloud Messaging not sending aps payload in correct format for iOS Notification Content & Service Extensions 在 iOS 上未收到 Firebase 云消息传递通知 - Firebase Cloud Messaging notification not received on iOS Firebase Cloud Messaging iOS:无后台推送通知 - Firebase Cloud Messaging iOS: No background push notification Firebase 云消息未收到通知 (iOS) - Firebase Cloud Messaging Not Receiving Notification (iOS) iOS中的GCM(Google云消息传递)(通知和数据有效载荷。) - GCM(Google Cloud Messaging ) in iOS( notification and data payload.) iOS Google Cloud Messaging有效负载 - iOS Google Cloud Messaging payload 使用PHP中的Google Cloud Messaging将通知发送到IOS和Android - Sending Notification To IOS And Android using Google Cloud Messaging in PHP 如何使用Firebase Cloud Messaging自动增加iOS通知徽章? - How to auto increment iOS notification badge with Firebase Cloud Messaging? 无法将通知发送到iOS(iPhone)Firebase云消息传递 - Can Not Send Notification to iOS (iPhone) Firebase Cloud Messaging 将Firebase Cloud Messaging发送到Android,但iOS失败。 如何为iOS构建有效负载? - Firebase Cloud Messaging to Android works but iOS fails. How to structure payload for iOS?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM