Firebase Cloud Messaging Notification not sending iOS payload format
Asked Answered
H

9

14

Last night I test push notification using FCM in my apps and it's crashed (It was working few days back). I test it using notification menu in firebase console.

I further investigate the notification payload format was changed and doesn't include the iOS format like the one in the Apple Documentation.

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.

I submitted a feedback to firebase team and the said it was an issue in their end. (Note: I also post the firebase team response in the link above). My Dev APNs Certificate is back, but the format the still the same.

Here's the payload i got (from Swift Print function)

{
    "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.

And based on this FCM documentation for iOS

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
  • I also submit another feedback but the Firebase Team not reply it yet

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

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. Also my notification handler will not working when the apps in foreground.

Edit 2:

I already register notification in my 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.

Capabilities

Edit 28 June 2016:

I tried again pushing notification from firebase console, and still i got the same payload format like this

%@ [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

Firebase Console Setting

Edit 8 July 2016:

This is my AppDelegate code

@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
Homoeroticism answered 18/6, 2016 at 9:5 Comment(3)
Hey I am having the same issue. My aps key is missing as well. Have you found any solution?Valence
unfortunately not yet, i already contacting Firebase Support but sadly they are slow to respond (the status is we're investigating).Homoeroticism
Have you found the solution for this?Francie
U
5

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

I resolved issue with adding 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.

Ofcourse for production enviromnent use FIRInstanceIDAPNSTokenTypeProd

Unconventional answered 6/7, 2016 at 12:36 Comment(1)
hi, i tried your suggestion but it doesn't work for me :(Homoeroticism
H
1

The 'payload' you are printing looks right to me. However, note that this is not the APN payload. It is actually a dictionary of user-info. If I understand your question, you seem to be worried about the "aps" field being missing. 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):

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

And press the home key and wait.

Hennahane answered 22/6, 2016 at 10:0 Comment(1)
yes, i'm aware about the push notification capabilities, i'm running in real device, my apps is running in background, but nothing. like i said before, my apps working fine few days back, i receive the aps payload format, but now is not working :(, Thanks for your answer though.Homoeroticism
H
0

The 'payload' that you have provided was (presumably) produced by last line of the didReceiveRemoteNotification method, i.e. 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.

Hennahane answered 21/6, 2016 at 11:47 Comment(3)
Hi thanks for your answer, i try to explain it clearly, check the EDIT section :)Homoeroticism
Yes, there is no field by that name in the userInfo (as you can see from the result of print("%@", userInfo)). I suspect it is a relic from when firebase was GCM, and is a mistake in the example code provided by firebase. Just delete it, it's not needed!Hennahane
When you say "i don't get 'aps' payload format", remember that you are just printing the 'userInfo' object, not the actual payload. Are you running in the simulator or on a real device?Hennahane
W
0

I'm looking into why your gcm.message_id is null, give me a couple of days.

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

Also, make sure in Xcode you've set your capabilities to allow for background notifications to be handled.

Whity answered 23/6, 2016 at 19:14 Comment(11)
Hi thanks, abput register for remote notification enable push and remote notification in xcode capabilities i already done that, check my Edit 2Homoeroticism
I'm travelling so wont be able to look into this deeply until Tuesday. The code I linked has a fallback clause for non iOS 8 -- have you implemented that? Also, have you done the Firapp.Configure() Finally, if it was working, and stopped around the time that there was problems uploading the .p12, have you tried generating a new one and uploading that? Wondering if something got corrupted.Whity
my apps only support iOS 8 an above also i use iOS 9.3 device, i have done FIRApp.configure(), i also re upload my .p12. I will try to generate the .p12 againHomoeroticism
regenerate my .p12 upload to firebase console, try to send notification from firebase console, still got the same payload :(Homoeroticism
I just tried again, and used the following line of code in didReceiveRemoteNotification: NSLog(@"%@",userInfo[@"aps"]); ...and it works fine, I see the message sent in FN there.Whity
And do your settings look like this? storage.googleapis.com/blogstuff-lmoroney/…Whity
Hi it's really strange i still got the same format, see updateHomoeroticism
I am checking as to why you would get that format. When I send a notification through the FN console I get: %@ [google.c.a.c_l: Yahahah, Custom Key1: Foo, gcm.n.e: 1, google.c.a.e: 1, Custom Key2: Bar, Custom Key3: Baz, google.c.a.c_id: 654004589921730800, gcm.message_id: 0:1467146177365242%a5da8cc7a5da8cc7, gcm.notification.sound2: default, google.c.a.udt: 0, aps: { alert = { body = "Yahoo!"; title = Test; }; badge = 3; sound = default; }, google.c.a.ts: 1467146176]Whity
Can you post any of your code? Are you, for example, doing any GCM/FCM registration in your app?Whity
Hi Laurence, sorry for late reply, i'm on vacation this week, i just test it again its still the same, i update my question with my app delegate and full log of my apps hope that helps you :)Homoeroticism
Is it mandatory to get payload in similar format ,i am getting something like this %@ [from: 730307127978, itemId: 5858bd87e4b0d0e761b1acb6, viewed: false, createdTS: 1482211014645, notificationToName: Uma Madhavi, notificationType: ISUPPORT_UPDATED, collapse_key: do_not_collapse, actionByName: Uma Madhavi] but did receive notification method is not calling.Nez
F
0

Same problem here. In addition, Firebase messsage with key 'aps' seems not to be delivered while sending with console. Must be some bugs with Firebase for changing payload format.

About getting Firebase notify in background mode, in this case, I think iOS won't recognize the payload format -> no notify at all. To read message from Firebase on background, don't call FIRMessaging.messaging().disconnect() when moving to background mode. Then you should get your message and handle it by your own handle (still no system notification).

Ferdinana answered 29/6, 2016 at 7:33 Comment(0)
V
0

I went through the developers forum of Apple and it seems that didRegisterForRemoteNotificationsWithDeviceToken wasn't working in SandBox mode and worked only in Production. didRegisterForRemoteNotificationsWithDeviceToken is where I register the deviceToken with firebase. Since that wasn't happening, Firebase was sending payload with notification key as it did not know the device was Apple. Today Apple fixed the issue and now I am able to send notifications.

Valence answered 20/7, 2016 at 7:51 Comment(1)
Thank watson, it's really strange but my problem still occur. I'm using my own server to send APN atm.Homoeroticism
C
0

I hade the same problem, I added 'high' priority and it worked for me !

{
    "collapse_key" :"com.xxx.xxx",
    to: "xxx",
    priority : "high",
    notification :{..}
}
Crowther answered 22/9, 2016 at 15:29 Comment(0)
S
0

To coerce ios simulator to digest .apns destined for firebase "aps" dictionary had to be copied and pasted to the top level next to "apns" and Co.

Shuman answered 22/6, 2023 at 12:59 Comment(0)
I
-3

switch your wifi/mobile data will do the tricks.

Inesinescapable answered 17/7, 2020 at 18:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.