MaikuB / flutter_local_notifications

A Flutter plugin for displaying local notifications on Android, iOS, macOS and Linux
2.47k stars 1.4k forks source link

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

Open ariona opened 10 months ago

ariona commented 10 months ago

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,
     )
  ),
);
MaikuB commented 10 months ago

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

agonzalezpuerta commented 9 months ago

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

Jan-Stepien commented 9 months ago

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

agonzalezpuerta commented 9 months ago

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
    }
Jan-Stepien commented 9 months ago

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...

lsxu commented 8 months ago

The same problem
iOS 17.0

sinanhaci commented 6 months ago

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

bichoalexis commented 6 months ago

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.

singhvedant commented 6 months ago

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?

sadhan46 commented 5 months ago

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

Pierre-Monier commented 5 months ago

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)

  }
}
vladislove80 commented 5 months ago

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.

saurabhDetharia commented 3 months ago

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).

Brechard commented 3 months ago

same here as @vladislove80 , working with 17.0.0 but not 17.1.2

kacbrz commented 1 month ago

hi, anyone got it working?

LiamMarega commented 1 week ago

Same issue here