0
votes

Using Firebase to send IOS notification. I click the notification message on my iphone, it start the app and close the app immediately. I don't know what I did wrong, Could you please help to solve this issue?

Here with the code of AppDelegate.swift

import UIKit
import Firebase
import FirebaseMessaging

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?


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


    //add it for firebase
    FIRApp.configure()

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


    // Override point for customization after application launch.
    return true
}

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

func applicationWillEnterForeground(application: UIApplication) {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

func applicationDidBecomeActive(application: UIApplication) {
    // 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:.
}

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {


    print("MessgaeID : \(userInfo["gcm_message_id"]!)")
    print(userInfo)


}

}

2016-09-17 00:25:35.709 mediation[922:20184] Configuring the default app. 2016-09-17 00:25:35.724 mediation[922:] Firebase Analytics v.3402000 started 2016-09-17 00:25:35.725 mediation[922:] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled 2016-09-17 00:25:35.729: FIRInstanceID AppDelegate proxy enabled, will swizzle app delegate remote notification handlers. To disable add "FirebaseAppDelegateProxyEnabled" to your Info.plist and set it to NO 2016-09-17 00:25:35.729: Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(null)" 2016-09-17 00:25:35.731: FIRMessaging library version 1.2.0 2016-09-17 00:25:35.734: FIRMessaging AppDelegate proxy enabled, will swizzle app delegate remote notification receiver handlers. Add "FirebaseAppDelegateProxyEnabled" to your Info.plist and set it to NO 2016-09-17 00:25:35.752 mediation[922:] Successfully created Firebase Analytics App Delegate Proxy automatically. To disable the proxy, set the flag FirebaseAppDelegateProxyEnabled to NO in the Info.plist 2016-09-17 00:25:35.785 mediation[922:] Firebase Analytics enabled 2016-09-17 00:25:35.813: Failed to fetch APNS token Error Domain=NSCocoaErrorDomain Code=3010 "REMOTE_NOTIFICATION_SIMULATOR_NOT_SUPPORTED_NSERROR_DESCRIPTION" UserInfo={NSLocalizedDescription=REMOTE_NOTIFICATION_SIMULATOR_NOT_SUPPORTED_NSERROR_DESCRIPTION}

2
Could you post your complete error message? Also, print out userinfo first, I'm guessing the gcm_message_id key doesn't exist.ohr
please see the error messageEric Chong
please kindly let me know how to print the userinfoEric Chong

2 Answers

0
votes

I think the your gcm_message_id does not exists! The gcm_message_id it's inside a userInfo!

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    print("MessgaeID : \(userInfo["gcm_message_id"]!)")
    print(userInfo)
}

Try to print your userInfo to show all your received data. :)

0
votes

While I personally believe your error may be attributed to a miss-spelling of "MessageID" in your code:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {


print("MessgaeID : \(userInfo["gcm_message_id"]!)")
print(userInfo)

}

In case that doesn't happen to be the problem, try this:

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
    // Let FCM know about the message for analytics 
    FIRMessaging.messaging().appDidReceiveMessage(userInfo)

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

    // Print full message.
    print("%@", userInfo)


}

In any case, your AppDelegate should look like the following:

import UIKit
import Firebase
import FirebaseInstanceID
import FirebaseMessaging

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?
var alertTitle: String?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Continue to play users music from iTunes/Apple Music/ third party music streaming services 
    try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
    // Register for remote notifications
    if #available(iOS 8.0, *) {
        // [START register_for_notifications]
        let settings: UIUserNotificationSettings =
            UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
        application.registerUserNotificationSettings(settings)
        application.registerForRemoteNotifications()
        // [END register_for_notifications]
    } else {
        // Fallback
        let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound]
        application.registerForRemoteNotificationTypes(types)
    }

    FIRApp.configure()

    // Add observer for InstanceID token refresh callback.
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.tokenRefreshNotification),
                                                     name: kFIRInstanceIDTokenRefreshNotification, object: nil)

    return true
}

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    print("didRegisterForRemoteNotificationsWithDeviceToken()")
    // if FirebaseAppDelegateProxyEnabled === NO:
    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: .Sandbox)
    print("APNS: <\(deviceToken)>")
}

func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
    print("Registration for remote notification failed with error: \(error.localizedDescription)")
}

// [START receive_message]
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

    // Let FCM know about the message for analytics 
    FIRMessaging.messaging().appDidReceiveMessage(userInfo)

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

    // Print full message.
    print("%@", userInfo)


}
// [END receive_message]

// [START refresh_token]
func tokenRefreshNotification(notification: NSNotification) {
    if let refreshedToken = FIRInstanceID.instanceID().token() {
        print("InstanceID token: \(refreshedToken)")
    }

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

// [START connect_to_fcm]
func connectToFcm() {
    FIRMessaging.messaging().connectWithCompletion { (error) in
        if (error != nil) {
            print("Unable to connect with FCM. \(error)")
        } else {
            print("Connected to FCM.")
        }
    }
}
// [END connect_to_fcm]

func applicationDidBecomeActive(application: UIApplication) {
    connectToFcm()
}

// [START disconnect_from_fcm]
func applicationDidEnterBackground(application: UIApplication) {
    FIRMessaging.messaging().disconnect()
    print("Disconnected from FCM.")
}
func applicationWillEnterForeground(application: UIApplication) {
    NSNotificationCenter.defaultCenter().postNotificationName("continueVideo", object: nil)
}

func applicationWillTerminate(application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    // Saves changes in the application's managed object context before the application temrinates.
  }

}

Either should work. I am also using FCM to implement remote push notifications in my app from my Firebase console and I'm using Firebase version 3.5.2 and this works perfectly for me, as a matter of fact, I just tested the above again and ran it in my device and I can receive a notification, swipe and be directed back into the app.