Search code examples
iosswiftnotificationsbackgroundapple-push-notifications

iOS Handle notifications and payload when app is in Background


I'm developing an Swift iOS 14 app that send and recieves push notifications from Firebase Cloud Messaging.

From FCM I send a message with a payload that must be treated by the app, updating an internal SQLite database with the payload data for later, show items in a view.

When the app is in Foreground, I recieved the notification in the didReceiveRemoteNotification method and update the database but when the app is in Background or killed, the notification is recieved but no one method is called to handle the payload and update de database.

I've read many topics about this problem but in none have I come to find a solution.

At the moment I don't want to use an external database to insert the data, and later read the external database, but if there is no other options i will change the app (the reason is that i don't want to store any information out of the user application).

My AppDelegate.swift is the following:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        //Firebase Auth + APNs
        FirebaseApp.configure()
        UNUserNotificationCenter.current().delegate = self
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: {_, _ in })
        application.registerForRemoteNotifications()
        Messaging.messaging().delegate = self
        return true
    }

func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
    UserDefaults.standard.set(fcmToken, forKey: UserConstants.MESSAGING_TOKEN)
    let dataDict:[String: String] = ["token": fcmToken]
      NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    if(userInfo["name"] != nil) {
        ContactsService.sharedInstance.addAlert(phoneNumber: userInfo["phone"] as! String, name: userInfo["name"] as! String, isLocalized: Bool(userInfo["isLocalized"] as? String), longitude: (userInfo["longitude"] as! NSString).doubleValue, latitude: (userInfo["latitude"] as! NSString).doubleValue)
    }
}

Can someone help me, telling me if it's possible to do in that way or it's necessary to store the data externally to later retrieve it?

Thank you!


Solution

  • There are two types of push notifications, alert notifications and background notifications. Alert notifications allow you to deliver visible alerts that can be interacted with in ways that your app can customize.Background notifications allow your application to fetch data from the background, upon receiving push notifications. Background notification should be used to keep your application up to date, even if the application isn't running. Also as of ios 10(and above)instead of using the didReceiveRemoteNotification method you can use didReceive method for handling the alert notifications.

    Now coming back to your question in case of the alert notification the didReceive/didReceiveRemoteNotification method is called when the application is in the foreground or when the user taps on the application. Since, you want to update the database you can use the background notifications instead of the alert notification as it will automatically raise your application even when it is in background and will also call the didReceiveRemoteNotification:fetchCompletionHandler. while sending a background push notification make sure you :

    • Edit Info.plist and check the "Enable Background Modes" and "Remote notifications" check boxes.
    • Add "content-available":1 to your push notification payload, otherwise the app won't be woken if it's in the background
    • The notification’s POST request should contain the apns-push-type header field with a value of background, and the apns-priority field with a value of 5.

    For more info please refer : https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app