OneSignal / OneSignal-Flutter-SDK

OneSignal is a free push notification service for mobile apps. This plugin makes it easy to integrate your flutter app with OneSignal
https://www.onesignal.com
Other
608 stars 206 forks source link

[Bug]: OneSignal.Notifications.addClickListener does't fire on cold start #807

Open wasilni2022 opened 7 months ago

wasilni2022 commented 7 months ago

What happened?

Hello, I'm using one signal 5.0.4 I have tested the notifications on real android device running android 33

OneSignal.Notifications.addClickListener is not working when the app is killed completely. it's works only if the app is running on foreground or background but not when completely killed.

Steps to reproduce?

1. OneSignal.Notifications.addClickListener not called

What did you expect to happen?

Once the user clicked on the notification on phone appbar, the app should open and fire ClickListener, but the app is opened without firing the listener.

OneSignal Flutter SDK version

5.0.4

Which platform(s) are affected?

Relevant log output

No error or warning log from the package.

Code of Conduct

nan-li commented 7 months ago

Hi @wasilni2022, You are seeing this behavior on both iOS and Android?

Can you share your OneSignal initialization code, and where you call OneSignal.Notifications.addClickListener(listener)?

wasilni2022 commented 7 months ago

Hi @wasilni2022, You are seeing this behavior on both iOS and Android?

Can you share your OneSignal initialization code, and where you call OneSignal.Notifications.addClickListener(listener)?

Hello nan, I tested it on Android only. Here is the code:

static String? _initializedAppId;

static void initialize({
    required final String appId,
    final VoidCallback? onSuccess,
    final VoidCallback? onError,
  }) {
    try {
      if (_initializedAppId != appId) {
        OneSignal.initialize(appId);
        _initializedAppId = appId;
      }
      onSuccess?.call();
    } catch (_) {
      onError?.call();
    }
  }

This initialization code is called once when the app is launched.

Here is the code for adding the listeners:

Future<void> _initOneSignal() async {
    await _checkAppNotificationsAcceptance();
    OneSignal.Notifications.addForegroundWillDisplayListener(_onForegroundNotification);
    OneSignal.Notifications.addClickListener(_onBackgroundOpenedNotification);
  }

This code is called when the app is launched and the user is signed in.

Once the user is signed out, I invoke these methods:

OneSignal.Notifications.removeForegroundWillDisplayListener(_onForegroundNotification);
OneSignal.Notifications.removeClickListener(_onBackgroundOpenedNotification);
romanfurman6 commented 5 months ago

@wasilni2022 Hey, any updates on this? Did you have a chance to fix it?

wasilni2022 commented 5 months ago

@wasilni2022 Hey, any updates on this? Did you have a chance to fix it?

Seems like it is working perfectly on release mode.

Thanks

nan-li commented 4 months ago

Hi @wasilni2022 thanks for following up, it was a difference in behavior on debug vs release mode?

@romanfurman6 You are also seeing this same issue?

wasilni2022 commented 4 months ago

Hi @wasilni2022 thanks for following up, it was a difference in behavior on debug vs release mode?

@romanfurman6 You are also seeing this same issue?

Unfortunately, the issue still exists on iOS and Android even with release mode (but without publishing to stores), however, it is only working when the app is published to stores (tested on Android only).

wasilni2022 commented 4 months ago

@wasilni2022 Hey, any updates on this? Did you have a chance to fix it?

It is only working when the app is published to stores (tested on Android only).

albertpak commented 1 month ago

issue still existing on iOS, and we are using OneSignal v5.1.0

wasilni2022 commented 1 month ago

issue still existing on iOS, and we are using OneSignal v5.1.0

Unfortunately, yes, it still exists.

Sometimes it is work as expected, most times not work.

albertpak commented 1 month ago

are there any plans on fixing the issue?

issue still existing on iOS, and we are using OneSignal v5.1.0

Unfortunately, yes, it still exists.

Sometimes it is work as expected, most times not work.

nan-li commented 1 month ago

Hi @wasilni2022 and @albertpak, thanks for following up. It is odd there is a difference in debug vs release vs published versions of the apps, but I have seen some issues before with running Flutter apps in debug vs release.

I am not able to reproduce based on my testing scenario. I add the click listener after initialization at app startup:

OneSignal.initialize("app_id")
OneSignal.Notifications.addClickListener(listener)

@wasilni2022 I notice you mention adding the listener after logging in a user and removing the listener after logging out. The listener should be added early in the app startup process in order to capture the click event. Just to test, can you try adding the listener at app startup?

To clarify, Android is working in store published mode? And iOS is sometimes working in store published mode?

My hunch that the sometimes working or not working is the flaky time gap between the app cold starting and the click listener being added to capture the event.


@albertpak Can you tell me about when you are adding the click listener, and Android is working as expected?

albertpak commented 1 month ago

will let you know...but again...our issue is with OneSignal's iOS package, and I'm attaching a dummy app that we made that replicates the problem.

TestOneSignal.zip


Hi @wasilni2022 and @albertpak, thanks for following up. It is odd there is a difference in debug vs release vs published versions of the apps, but I have seen some issues before with running Flutter apps in debug vs release.

I am not able to reproduce based on my testing scenario. I add the click listener after initialization at app startup:

OneSignal.initialize("app_id")
OneSignal.Notifications.addClickListener(listener)

@wasilni2022 I notice you mention adding the listener after logging in a user and removing the listener after logging out. The listener should be added early in the app startup process in order to capture the click event. Just to test, can you try adding the listener at app startup?

To clarify, Android is working in store published mode? And iOS is sometimes working in store published mode?

My hunch that the sometimes working or not working is the flaky time gap between the app cold starting and the click listener being added to capture the event.

@albertpak Can you tell me about when you are adding the click listener, and Android is working as expected?

SVyatoslavG commented 1 month ago

I am experiencing the same issue on iOS (I did not test it on Android). I can confirm having the same problem: Sometimes it works as expected, but most times it does not work.

nan-li commented 1 month ago

How are people testing the click listener on a cold start? Are you relying on print statements only?

albertpak commented 1 month ago

How are people testing the click listener on a cold start? Are you relying on print statements only?

Can you provide us with a project that includes working navigation to display a specific ViewController, as we have previously sent to you? We've sent you .zip file an example where it doesn't work, and your response was along the lines of "Our SDK engineer was not able to reproduce after taking your code and integrating it within their minimal project." Can you share that implementation?

Including one of methods and log when pressed. image

image

nan-li commented 1 month ago

Hi @albertpak, I believe your example project you sent to our support team did not have navigation in the click listener callback, only a print statement. Your project had some build errors for me so I just copied what was in the AppDelegate into a minimal project.

This is how I attempted to reproduce with your code:

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    let notificationHandler = Event()

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

        OneSignal.Debug.setLogLevel(.LL_VERBOSE)

        OneSignal.initialize("app_id", withLaunchOptions: launchOptions)

        OneSignal.Notifications.requestPermission({ accepted in
            print("User accepted notifications: \(accepted)")
        }, fallbackToSettings: true)

        OneSignal.Notifications.addClickListener(notificationHandler)
        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) { }
}

class Event: NSObject, OSNotificationClickListener {
    func onClick(event: OSNotificationClickEvent) {
        print("[DEBUG] >> Clicked") // this does not always print!
        try! foo() // But the app crashes 100% of the time when I click a notification from cold start
    }

    func foo() throws {
        throw NSError()
    }
}

You bring up 2 separate concerns:

  1. The click listener not firing: how are you testing if it is firing or not, since print statements are not reliable? I recommend setting and checking some local state variable. This would be an SDK bug if it is not firing.
  2. Navigating within the click listener callback: This is outside the scope of the SDK. It may be on cold start, this is too early, etc.
henrybeboy11 commented 1 week ago

Hi, is there any update on this issue, I am expecting just like other cold start issue, maybe if you can implement a getInitialNotification() method that can get the notification from cold start(clicked notification). So aside from addClickListener which will be used for Hot/Warm Start we have this getInitialNotification() for Cold Start.