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
60 stars 16 forks source link

How to check if setOnBackgroundMessage() is called while in terminated state? #478

Open asoap opened 1 year ago

asoap commented 1 year ago

Hey hey,

I'm using background push notifications and awesome_notification to create local notifications. So far it's working rather well, so thank you.

I'm calling: ably.Push.notificationEvents.setOnBackgroundMessage()

Which does wake up the app when it's been terminated. But by looking at the adb log I can see that the app wakes up and behaves like normal. As if the user launched it. This is problematic as we automatically login our user. So if they get a notification the app wakes up, logs in the users, displays the notification and then terminates. Then if another notification comes in, it does this all over again.

Is there anyway to tell if the app is being launched by Ably and the backgroundMessage?

┆Issue is synchronized with this Jira Task by Unito

sync-by-unito[bot] commented 1 year ago

➤ Automation for Jira commented:

The link to the corresponding Jira issue is https://ably.atlassian.net/browse/SDK-3852

asoap commented 1 year ago

I'm adding this in here just because I went through two days of hell with Android. Whenver I recieved a background message it would work if the app was in the background. But as soon as the app was terminated it would be launched as an isolate and it would get the message using the setOnBackgroundMessage() handler. But then it would fail to produce the notification. It didn't matter if I used fluter_local_notification or awesome_notifications. This is the error I was getting.

Tried to send a platform message response, but FlutterJNI was detached from native C++. Could not send. Response ID: 10
Failed to handle method call
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.canCreateNotificationChannel(FlutterLocalNotificationsPlugin.java:421)

I tracked the issue down to the line in the flutter_local_notifications code:

(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

But the issue was that sometimes in an earlier version of my app it DID work. It seemed to me like the isolate would close while the setOnBackgroundMessage() function was still firing. Say if I added in a delay in the function it would die before the delay finished.

Similarly I added prints into my handler method to see what was going on.

--- in here 1
--- in here 3
--- in here 4
--- in here 5
(INFO): io.ably.lib.realtime.AblyRealtime: started
(INFO): TokenAuth.setTokenDetails():
(INFO): Auth(): using token auth with authCallback
Tried to send a platform message response, but FlutterJNI was detached from native C++. Could not send. Response ID: 10
Failed to handle method call
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference

What was strange was the Ably (INFO) message outputting before my notification call happened. I then came up with this idea. That because I was adding the background message handler first, and then doing the Ably connect stuff, it was screwing up the background call and it was killing the isolate before hte background message could complete.

So I just did the connect stuff first:

ably.ClientOptions clientOptions = ably.ClientOptions();
ablyClient = ably.Realtime(options: clientOptions);

Then add the background message handler:

ably.Push.notificationEvents.setOnBackgroundMessage(NotificationController.bacgroundMessageHandler);

That was a really painful two days of work.