ably / ably-flutter

A wrapper around our Cocoa and Java client library SDKs, providing iOS and Android support for those using Flutter and Dart.
https://ably.com/download
Apache License 2.0
59 stars 14 forks source link

Getting push notification on android terminate state #434

Open ali-almas opened 2 years ago

ali-almas commented 2 years ago

I have problem on Android devices that I get notifications only on background and foreground state. If app is in the terminate state, app does not get any notification

┆Issue is synchronized with this Jira Task by Unito

QuintinWillison commented 2 years ago

Thanks for the report. We're likely to need more information from you in order to diagnose or attempt to reproduce this. Have you followed all of the Android steps in our Flutter-specific Push Notifications documentation? Could you double check? Is there anything else in that document that might help you, perhaps?

ali-almas commented 2 years ago

Yes, I have followed all the steps. And I do not use firebase_messaging. I only use ably. I get notification on backround and foreground state and not in terminate state.


Future<void> activatePushNotification() async {
  try {
    print("REGISTERING USER ID FOR NOTIFICATION = $userId");
    realtime.push.deactivate();

    if (Platform.isIOS) {
      final granted = await realtime.push.requestPermission();
      if (granted) await realtime.push.activate();
    } else if (Platform.isAndroid) {
      AndroidPushNotificationConfiguration();
      realtime.push.activate();
    }
  } on ably.AblyException catch (error) {
    log("ERROR ON ACTIVATION OF PUSH = $error");
  }
}
QuintinWillison commented 2 years ago

I've not tried it myself, but reading that document I note that we have a setOnBackgroundMessage method that you need to supply a callback to. Have you done that?

From the Data Message / Background Notification section in the aforementioned documentation:

When the app is terminated or in the background, you can listen to messages using:

Future<void> _backgroundMessageHandler(ably.RemoteMessage message) async {
  print('Just received a background message, with:');
  print('RemoteMessage.Notification: ${message.notification}');
  print('RemoteMessage.Data: ${message.data}');
}
ably.Push.notificationEvents.setOnBackgroundMessage(_backgroundMessageHandler);

This method can be synchronous or async. On Android, when a message is received whilst the app is terminated, Ably Flutter will launch your application to process the message. Ably Flutter listens to the message by registering a broadcast receiver. This means your MainActivity will not be launched, and so your native setup code (e.g. creating method channels) you may have written in your MainActivity's configureFlutterEngine method will not be run. If you want your configureFlutterEngine to run even when Ably launches your application, refactor this code into a Flutter package plugin, implementing FlutterPlugin and move your logic inside onAttachedToEngine.

ali-almas commented 2 years ago

Yes I have set it. Still not getting any notification on android terminate state. iOS works perfectly. Android background and foreground works perfectly. Only android terminate state is problem

static void setUpMessageHandlers() {
    getLaunchMessage();

    notificationEvents
      ..setOnBackgroundMessage(_backgroundMessageHandler)
      ..setOnOpenSettings(() {
        print('The iOS user has asked to see the In-app Notification Settings');
      });

    notificationEvents.onMessage.listen((message) {
      addMessage(message);
      print('RemoteMessage received while app is in foreground:\n'
          'RemoteMessage.Notification: ${message.notification}'
          'RemoteMessage.Data: ${message.data}');
    });

    notificationEvents.setOnShowNotificationInForeground((message) async {
      print('Opting to show the notification when the app is in the foreground.');
      return true;
    });

    notificationEvents.onNotificationTap.listen((remoteMessage) {
      addMessage(remoteMessage);
      print('Notification was tapped: $remoteMessage');
    });
  }
davyskiba commented 1 year ago

@ali-almas This might be related to battery optimizations, could you give us more information about your setup? What device and system version are you testing on? What compileSdk and targetSdk is set in the app build.gradle? Is the issue occurring on both debug and release build variants?

JakubJankowski commented 1 year ago

@ali-almas Also, how are you putting your app in a terminated state? If you're "force stopping" it from the settings, then it looks like it's working as intended. If that's the case, please take a look here, and especially:

Note that the system adds [FLAG_EXCLUDE_STOPPED_PACKAGES](https://developer.android.com/reference/android/content/Intent#FLAG_EXCLUDE_STOPPED_PACKAGES) to all broadcast intents. It does this to prevent broadcasts from background services from inadvertently or unnecessarily launching components of stoppped applications. A background service or application can override this behavior by adding the [FLAG_INCLUDE_STOPPED_PACKAGES](https://developer.android.com/reference/android/content/Intent#FLAG_INCLUDE_STOPPED_PACKAGES) flag to broadcast intents that should be allowed to activate stopped applications.

Applications are in a stopped state when they are first installed but are not yet launched and when they are manually stopped by the user (in Manage Applications).

I've tested the Example app a bit with my android device (Redmi note 9 pro), and it adheres to this behaviour - if I force stop the app, I'll stop getting any notifications.