OneSignal / OneSignal-Cordova-SDK

OneSignal is a free push notification service for mobile apps. This plugin makes it easy to integrate your Ionic, PhoneGap CLI, PhoneGap Build, Cordova, or Sencha Touch app with OneSignal. Supports Android, iOS, and Amazon's Fire OS platforms. https://onesignal.com
Other
251 stars 197 forks source link

Receiving notifications if the app is not open for one month and android onTokenRefresh/onNewToken when app is not running #679

Closed sagits closed 6 months ago

sagits commented 3 years ago

Description: Hi, I work with Ionic development. All my apps have a problem with notifications because the official Ionic plugins cant handle the "onTokenRefresh()/onNewToken()" method when the app is closed. This means that when the Android app is not used for 1 month and the device token changes on Google Firebase, the user stops receiving notifications until he opens the app again (what will trigger the on token refresh functions and save the new token).

I would like to know if OneSignal Cordova plugin handles this case? Will my users receive notifications in background if they don't open the app for 1 or 2 months? Thanks in advance.

(your description here)

Environment Cordova 8 Ionic 5

Steps to Reproduce Issue:

  1. Install app with notification plugin
  2. Close the app and don't open it for 1 month

Anything else:

I tried to find some clues in the plugin code or in GitHub issues, but I didn't find anything related to this question.

jkasten2 commented 3 years ago

@sagits Thanks for raising this issue. I wasn't able to find a expire after 1 month note on Google's Firebase documentation. I checked the following pages.

Is this a behavior observed or can you link to where you found the expire time? In my testing I have never observed a 1 month expiration.

This Cordova plugin's Android native component is called OneSignal-Android-SDK but does not implement onTokenRefresh or onNewToken today.

However in Firebase's docs for onNewToken it notes "Called when a new token for the default Firebase project is generated." however the OneSignal-Android-SDK creates it's own FirebaseApp instance so it is possible expiration does not apply to OneSignal due to this. However it also doesn't explicitly say it is excluded from refresh events either. Something we can attempt to confirm from Firebase.

Ideally OneSignal should still implement onNewToken for the other rare edge cases though so the user does not have to open the app so it something we can look into as well.

sagits commented 3 years ago

Thanks for answering @jkasten2.

GetToken must be called in order to register the device to receive notifications and OnNewToken will be called every time the token of the device is updated on the Firebase Project. As per my understanding, OneSignal works as a layer to make things work the way they should and also to make things simpler for developers, but the Android push notifications are still being sent from FCM (which means the device token exists and can be updated from FCM).

image

In the documentation, it implies that the token can change and that when it changes you need to send it again to your server (otherwise you will not be able to send messages to this specific device). The old token lives for 24hours after being updated, so a device that has not called OnNewToken() yet will still receive messages sent to the old token for 24h.

The method OnNewToken() should be implemented in FirebasePluginMessagingService. The problem we had with the default cordovaFCM plugin was that OnNewToken() is called but it tries to send the new token to the app and the app is closed (the javascript bridge will not work because the app is not opened). Please check these images from the default Cordova Firebase Plugin (we consider that the app is closed because this can happen at any time, and our users are not using the app 24h a day):

image

image

callbackContext.sendPluginResult() is trying to send the token to the webview in order for it to send the token to your own server (in this case OneSignal), but the webview is not loaded (because the app is closed). To solve this problem, we need to call getToken() every time we open the app (in javascript) in order to send the new token to the server and be able to send messages to this device token. The problem is that if the user doesn't open the app, his token will never be updated on our server and we'll not be able to send messages to him.

The solution for this problem in OneSignal would be easy: use a native (not javascript) function to send the updated token to OneSignal server.

I've downloaded the OneSignal Android SDK and I found that there is a onNewToken() method that seems to do exactly what I described. But it's inside the HmsMessageServiceOneSignal/OneSignalHmsEventBridge file, this means that it only works for Huawei devices?

image

image

image

image

lastRegistrationId/id/identifier are the token (they are the same value, just different props names). It's being sent to OneSignal as the user identifier.

Thanks in advance.

eleonorarocchi commented 2 years ago

Hi, is there any new suggestion for this problem? I have the same problem too.

jkasten2 commented 2 years ago

@eleonorarocchi We do not have any updates at this time. If you have any more details or steps reproduce please let us know.