Silent push notifications not received

I have a flutter app which receives bot alert and silent notifications. The alert notifications are received properly whilst the silent ones do not trigger any function. My app is based on OneSignal but for the testing i am also trying to directly send the notifications using the APN console. Using either alert or background type notification

I am using real device (iPhone XR) The background modes are set to "Background fetch" and "Remote notifications" The token is valid as i am getting alert notifications. The app has notification permissions. The didReceiveRemoteNotification never gets triggered (for alert or silent types) When sending alert notification i do see the printout of "willPresent notification"

Here is my AppDelegate.swift code.

@objc class AppDelegate: FlutterAppDelegate {
    
    override func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        // Log device token to ensure correct registration
        let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
        let token = tokenParts.joined()
        print("Device Token: \(token)")
    }

    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Request full notification permissions
        UNUserNotificationCenter.current().requestAuthorization(
            options: [.alert, .badge, .sound, .provisional, .criticalAlert]
        ) { (granted, error) in
            print("Notification Authorization Granted: \(granted)")
            if let error = error {
                print("Notification Authorization Error: \(error.localizedDescription)")
            }
            
            // Always attempt to register for remote notifications
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
        
        // Set notification center delegate
        UNUserNotificationCenter.current().delegate = self
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    // Add this method to handle foreground notifications
    override func application(
        _ application: UIApplication,
        didReceiveRemoteNotification userInfo: [AnyHashable: Any],
        fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
    ) {
        print("🔔 FULL didReceiveRemoteNotification CALLED")
        print("Full Payload: \(userInfo)")

        // Detailed logging of APS dictionary
        if let aps = userInfo["aps"] as? [String: Any] {
            print("APS Dictionary: \(aps)")
            print("Content Available: \(aps["content-available"] ?? "Not Found")")
        }

        // Explicit silent notification check
        if let aps = userInfo["aps"] as? [String: Any],
           let contentAvailable = aps["content-available"] as? Int,
           contentAvailable == 1 {
            print("✅ CONFIRMED SILENT NOTIFICATION")

            // Perform any background task here
            completionHandler(.newData)
            return
        }

        print("❌ Not a silent notification")
        completionHandler(.noData)
    }


   
    override func application(
        _ application: UIApplication,
        performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
    ) {
        print("🔄 Background Fetch Initiated")
        // Perform any background fetch tasks
        completionHandler(.newData)
    }
    
    override func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        let userInfo = notification.request.content.userInfo
        
        print("**** willPresent notification ****")
        print("Full Notification Payload: \(userInfo)")
        
        // Explicitly log the aps dictionary
        if let aps = userInfo["aps"] as? [String: Any] {
            print("APS Dictionary: \(aps)")
            print("Content Available: \(aps["content-available"] ?? "Not Found")")
        }
        
        // Check for silent notification
        if let aps = userInfo["aps"] as? [String: Any],
           let contentAvailable = aps["content-available"] as? Int,
           contentAvailable == 1 {
            print("**** CONFIRMED SILENT NOTIFICATION IN FOREGROUND ****")
            completionHandler([])
            return
        }

        // For non-silent notifications
        if #available(iOS 14.0, *) {
            completionHandler([.banner, .sound])
        } else {
            completionHandler([.alert, .sound])
        }
    }
}

The behavior you are seeing is expected, and it is due to content-available (aka "background" or "silent") push notifications being throttled when being delivered to apps that are in the background.

Background push notifications are never guaranteed to be delivered to the app every single time.

Additionally, notifications sent at low priority (priority 5) are throttled, regardless of payload. And background push notifications must always be sent at low priority. While you may expect up to several 1 or 2 push notifications per hour across all apps on a device, it is entirely possible and appropriate that you may receive none at all. Additionally, these notifications will not be delivered to the app at all if the user has not launched the app for a while.

The throttle is disabled if you run your app with a debugger attached. This allows you to test that your notifications are being received correctly, but should only be considered a best-case scenario.

The important point is that apps should never be designed expecting that every background push notification will be received. This is not how APNs is intended to work; it is intended to inform the user or app that some event of interest has occurred. Apps are expected to work properly, albeit perhaps with degraded functionality, if push notifications are not received. The user can turn off push notifications or background app updates at any time, and of course push notifications will not be received if the device doesn’t have network connectivity.

Also, an app will not be woken in the background by a push notification if the app had previously been force-quit. Force quit is considered a drastic choice by the user to say that they do not want the app to run, often because it misbehaved in some unrecoverable manner.


Argun Tekant /  DTS Engineer / Core Technologies

Thank you for your reply.
I understand these limitations but my use case is different.
I only expect to get the notifications while my app is in the foreground.
So far i am testing with the debugger attached and still not getting the didReceiveRemoteNotification triggered.
The didReceiveRemoteNotification does not get triggered even for alert notification.
I only get the willPresent function triggered when receiving alert notification.
Any idea why the didReceiveRemoteNotification is not getting triggered?

Silent push notifications not received
 
 
Q