flutter_local_notifications icon indicating copy to clipboard operation
flutter_local_notifications copied to clipboard

[IOS] Notification not shown when the app is in foreground state

Open ariona opened this issue 1 year ago • 14 comments

Describe the bug

Notification did not shown when the app is in foreground state on IOS

To Reproduce Here is the code i use, i am setting all present option to true, but the notification did not show up. it's only showing up when the app is minimized.

await flutterLocalNotificationsPlugin.show(
  99,
  'title'
  'notification body',
  NotificationDetails(
    android: AndroidNotificationDetails(),
    iOS: DarwinNotificationDetails(
        sound: "adzan.aiff",
        interruptionLevel: InterruptionLevel.timeSensitive,
        presentSound: true,
        presentList: true,
        presentAlert: true,
        presentBadge: true,
        presentBanner: true,
     )
  ),
);

Expected behavior

As stated on readme, default behavior for IOS is to show notification even on foreground. But even after setting the presentation option to true it didn't show up.

For iOS 10+, use the presentation options to control the behaviour for when a notification is triggered while the app is in the foreground. The default settings of the plugin will configure these such that a notification will be displayed when the app is in the foreground.

Sample code to reproduce the problem

/// initialization part
final InitializationSettings initializationSettings = InitializationSettings(,
  iOS: DarwinInitializationSettings(
    defaultPresentAlert: true,
    defaultPresentBadge: true,
    defaultPresentBanner: true,
    defaultPresentSound: true,
    onDidReceiveLocalNotification: (int id, String? title, String? body, String? payload){
      print([id, title, body, payload]);
    },
    defaultPresentList: true
  )
);
await flutterLocalNotificationsPlugin.initialize(
  initializationSettings,
  onDidReceiveNotificationResponse: (response){
    print(["onDidReceiveNotificationResponse", response.actionId]);
  },
  onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
);


/// Calling notification part
await flutterLocalNotificationsPlugin.show(
  99,
  'title'
  'notification body',
  NotificationDetails(
    android: AndroidNotificationDetails(),
    iOS: DarwinNotificationDetails(
        sound: "adzan.aiff",
        interruptionLevel: InterruptionLevel.timeSensitive,
        presentSound: true,
        presentList: true,
        presentAlert: true,
        presentBadge: true,
        presentBanner: true,
     )
  ),
);

ariona avatar Jan 01 '24 16:01 ariona

Please check the example app first as this shows it is working. If you believe there's an issue then please fork the repo and update the example app so it can reproduce the issue. Given the example app shows this is working and how this is a common use case, I would think you are missing something in your app as I would otherwise expect a bug of this type to have resulted in more reports given how long the plugin has been available

MaikuB avatar Jan 19 '24 10:01 MaikuB

I am also finding this issue. @ariona, were you able to debug your app?

agonzalezpuerta avatar Feb 05 '24 07:02 agonzalezpuerta

Got the same - Followed the instruction and the iOS notification is visible only when you put your app in background. In the foreground the .show() method finishes with no error, yet no push is visible.

iOS 17.2

Jan-Stepien avatar Feb 06 '24 14:02 Jan-Stepien

The bug in our app was that the following code was missing in AppDelegate.swift, as indicated in the example app. Notifications now show in the foreground.

    // This is required to make any communication available in the action isolate.
    // https://github.com/MaikuB/flutter_local_notifications/blob/master/flutter_local_notifications/example/ios/Runner/AppDelegate.swift
    FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
        GeneratedPluginRegistrant.register(with: registry)
    }
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
    }

agonzalezpuerta avatar Feb 09 '24 17:02 agonzalezpuerta

The bug in our app was that the following code was missing in AppDelegate.swift, as indicated in the example app. Notifications now show in the foreground.

    // This is required to make any communication available in the action isolate.
    // https://github.com/MaikuB/flutter_local_notifications/blob/master/flutter_local_notifications/example/ios/Runner/AppDelegate.swift
    FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
        GeneratedPluginRegistrant.register(with: registry)
    }
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
    }

Unfortunatelly not in my case...

Jan-Stepien avatar Feb 14 '24 11:02 Jan-Stepien

The same problem
iOS 17.0

lsxu avatar Mar 19 '24 04:03 lsxu

If you are using OneSignal, add these to your AppDelegate file

override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        super.userNotificationCenter(center, willPresent: notification, withCompletionHandler: completionHandler)
    }
    
override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        super.userNotificationCenter(center, didReceive: response, withCompletionHandler: completionHandler)
    }

@lsxu @Jan-Stepien

sinanhaci avatar May 17 '24 11:05 sinanhaci

I had the same problem in my case I solved it with the code below:

@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

    if #available(iOS 10.0, *) {
    UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
                     completionHandler([.alert, .badge, .sound])
      }

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    
  }
}

Be careful, check that I'm returning the super.application at the end of the function body.

bichoalexis avatar May 18 '24 02:05 bichoalexis

I had the same problem in my case I solved it with the code below:

@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

    if #available(iOS 10.0, *) {
    UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
                     completionHandler([.alert, .badge, .sound])
      }

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    
  }
}

Be careful, check that I'm returning the super.application at the end of the function body.

Can you explain what you did here?

singhvedant avatar May 21 '24 12:05 singhvedant

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert, .badge, .sound]) }

got any solution for it i'm facing the same issue too

sadhan46 avatar May 24 '24 10:05 sadhan46

This is my working AppDelegate, similar to the one shared by @bichoalexis but it wasn't working for me until I move the userNotificationCenter out of the didFinishLaunchingWithOptions function :

import UIKit
import Flutter
import flutter_local_notifications

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
                  completionHandler([.alert, .badge, .sound])
  }

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
        GeneratedPluginRegistrant.register(with: registry)
    }

    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
    }

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)

  }
}

Pierre-Monier avatar May 27 '24 17:05 Pierre-Monier

This is my working AppDelegate, similar to the one shared by @bichoalexis but it wasn't working for me until I move the userNotificationCenter out of the didFinishLaunchingWithOptions function :

import UIKit
import Flutter
import flutter_local_notifications

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
                  completionHandler([.alert, .badge, .sound])
  }

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
        GeneratedPluginRegistrant.register(with: registry)
    }

    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
    }

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)

  }
}

did trick for me.

faced the same issue. everything was working fine with flutter_local_notifications: ^17.0.0

after update to: flutter_local_notifications: ^17.1.2 faced exactly the same described behavior.

vladislove80 avatar May 31 '24 11:05 vladislove80

Is there any update regarding this? I am also facing the same issue with 17.2.1 version on my iPhone 14Plus (OS 17.5.1).

saurabhDetharia avatar Aug 08 '24 09:08 saurabhDetharia