Push notification is not working when app is in background (minimized) - iOS
Asked Answered
G

1

6

I'm newbie to Swift, I am creating chat application, I need to send notification when app is in foreground or minimized.

But I am not getting the notification when app is minimized (it works when USB is connected.

  1. Enabled Remote notification

  2. Background Fetches in Xcode setup

  3. Enabled Push Notification

  4. Production APns certificate

Notification code:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let gcmMessageIDKey = "gcm.message_id"

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        FirebaseApp.configure()

        Messaging.messaging().delegate = self
        Messaging.messaging().shouldEstablishDirectChannel = true

        if #available(iOS 10.0, *) {

            UNUserNotificationCenter.current().delegate = self

            let authOptions: UNAuthorizationOptions = [.alert, .sound, .badge]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: {_, _ in })
        } else {
            let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(types: [.alert, .sound, .badge], categories: nil)
            application.registerUserNotificationSettings(settings)
        }

        application.registerForRemoteNotifications()

        NotificationCenter.default.addObserver(self, selector: #selector(tokenRefreshNotification(_:)), name: NSNotification.Name.InstanceIDTokenRefresh, object: nil)

        return true
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {

        Messaging.messaging().appDidReceiveMessage(userInfo)         
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        Messaging.messaging().appDidReceiveMessage(userInfo)

        let action = userInfo["action"] as! String
        let notification = UILocalNotification()
        notification.fireDate = NSDate() as Date
        notification.alertTitle = "test"
        notification.alertBody = "test"
        notification.alertAction = "Ok"
        UIApplication.shared.applicationIconBadgeNumber =  1
        UIApplication.shared.scheduleLocalNotification(notification)

        completionHandler(UIBackgroundFetchResult.newData)
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Unable to register for remote notifications: \(error.localizedDescription)")
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        print("APNs token retrieved: \(deviceToken)")

        // With swizzling disabled you must set the APNs token here.
        Messaging.messaging().apnsToken = deviceToken
    }       
}

@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        let userInfo = notification.request.content.userInfo

        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }

        completionHandler([.alert, .sound, .badge])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo

        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }

        print(userInfo)

        completionHandler()
    }
    @objc func tokenRefreshNotification(_ notification: Notification) {
            guard let token = InstanceID.instanceID().token() else {
            print("No firebase token, aborting registering device")
            return
        }
        print("No firebase token, aborting registering device")           
    }
}   

extension AppDelegate : MessagingDelegate {
    // [START refresh_token]
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        print("Firebase registration token: \(fcmToken)")
        Messaging.messaging().subscribe(toTopic: "/topics/channel_18")           
    }

    func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
        print("Received data message: \(remoteMessage.appData)")
    }        
}

FCM Payload:

 {
     "to" : "/topics/channel_18",
     "data" : {
      "action" : "NOTIFY",
      "message" : "{"text":"test" }"
     },
     "content_available" : true
    }

I have tried with Priority high and with Sound option but none works.

Please note that I am not using "notification" key as per client request. i am using only data-message in FCM payload

Please anyone help me to work notification when app is in background without USB connection.

Gainless answered 27/7, 2018 at 4:55 Comment(24)
Just to be clear: it works when app is in forgeround? but just doesn't work when you press home button?Qoph
1. "but i am not getting the notification when app is minimized (it works when USB is connected." what do you mean by this? 2. Are you testing on a physical device or you're using the simulator?Qoph
i am using physical deviceGainless
notification is not working when screen is lockedGainless
does it work when the app is in the background? ie Just pressing home and not locking the phone?Qoph
No it does not work, it works only app is in foregroundGainless
just to be sure, are you killing the app? ie you're double clicking home button and then swiping the app up? Also have you seen hereQoph
i am not killing the app. just minimizedGainless
On the iphone do you have background app refresh enabled? See thisQoph
yes its enabled for my appGainless
notification does not work when is in lock mode tooGainless
I have updated above my full AppDelegate.swift fileGainless
Can you edit and remove the comments from your code?Qoph
Aside from your edit, please make sure you see the entire linked question. Additionally I have two more suggestion: a) of all your first 3 steps (Enabled Remote notification Background Fetches in Xcode setup Enabled Push Notification) just unselect and then select again and try again. b) remove the "content-available" flag from your payload and try again and just validate if you get any sort of notification. If that doesn't work then I can't think of anything else :/Qoph
and as a last resort try testing with another device...Qoph
tried your points still background notification is not working, is it working for you ?Gainless
if i remove content-available: true then foreground notification is also not working since its s data-message notificationGainless
with information your providing, I think your payload is set incorrectly. I've never used Firebase. See here. Set your payload accordingly. Also note the comments below it. I'm guessing you're missing the notification object itself. Also based on the research done here it seems that you need to include both title and body fields for it to work.Qoph
i am not used notification in payload, since notification should handle only by app not OSGainless
What do you mean app not OS? Do you mean you want it to be silent notification only? And not send a visible user notification? If that's your case still just do what I said so that you can make sure it's working for non Silent notificationsQoph
yes Silent notification only i need, when app in background (app is minimized ) didReceiveRemoteNotification is not being calledGainless
Understood. Still add notification field and see if it works for nonSilent notificationQoph
it works with notification object in payload. but my requirement is with silent push notificationGainless
I've made an edit.Qoph
Q
2

If it works with non-Silent notification then all it means is:

  • Then payload is not correctly setup. Based on the answers provided to this question I'd just alter the placement of the content_available field into notification(and since you don't want a title body then just don't add title/body) or just into the payload itself until see it working.
  • I'd also make sure all the correct capabilities in Xcode are set (Enabled Remote notification, Background Fetches in Xcode setup, Enabled Push Notification). As mentioned previously uncheck and recheck all of them again.
  • And make sure Background App refresh is enabled for your app. This is NOT the same with your notifications. Obviously make sure your notifications are also enabled.:

enter image description here

  • But if you tried everything and it just doesn't work for 11.3 then it might be a bug. There is this other open question mentioned the same issue of yours. Run the app directly from tapping the app, ie not launching from Xcode and then use the console to see what it's logging related to the silent notification. If you're getting something like this:
default 13:11:47.178186 +0200   dasd    DuetActivitySchedulerDaemon Removing a launch request for application <private> by activity <private>   default com.apple.duetactivityscheduler

Then likely it's a bug similar to this iOS11 question. But you must open a new radar, because that radar was closed I believe because it was fixed!

Qoph answered 2/8, 2018 at 14:55 Comment(8)
notification (app in background) works in IOS10.2 but not works on latest IOS versionGainless
interesting. From my other answer I've linked a similar bug in iOS 11. But it was fixed by the 11.1 release. You're saying you're testing on 11.3, so you might just need to file a radar, if it doesn't work for this version only...Qoph
my ios version is 11.4.1 beta latest not, but still same issue, i have tried in IOS version 10.2 mobile it worksGainless
what is your version? 11.4.1 beta or not?Qoph
Version is 11.4.1(15G5077a)Gainless
then why is your question tagged with 11.3?!Qoph
same issue in 11.3 , yesterday only updated to 11.4.1 version same caseGainless
when app is minimized , i am not getting notification.Gainless

© 2022 - 2024 — McMap. All rights reserved.