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])
}
}
}