OneSignal / react-native-onesignal

React Native Library for OneSignal Push Notifications Service
Other
1.56k stars 371 forks source link

[Bug]: v5.0.1 Android - Push Notifications are not received after first app opening #1581

Open fmorau opened 9 months ago

fmorau commented 9 months ago

What happened?

Hello react-native-onesignal team,

I recently updated to v5.0.1 and experiencing an issue on Android where Push Notifications are not coming after first app opening. Whenever I collapse and expand the app - it starts coming.

I couldn't find any workaround to impact this behavior and enable notifications straight away, so I report it here. Any help or guidance would be greatly appreciated.

Thank you!

Steps to reproduce?

1. Install `react-native-onesignal` v5.0.1
2. Create `NotificationServiceExtension` for Android
3. Install & Launch the app 
4. Request user permission of `android.permission.POST_NOTIFICATIONS` via PermissionsAndroid.request
4.1. (optional - does not impact the result) Call OneSignal.login + Notifications.OptIn()
4.2. Call `getOptedIn` -> returns false (surprise)
5. `getPushSubscriptionId` and send it to backend for further REST API calls
6. Send push notifications to subscribed device via REST API from backend
AR: Push Notification is not received and even does not appear on app.onesignal dashboard, while it was sent from backend without any errors
7. Collapse and Open the app on Android
AR: `permissionChange` is fired only now. Push Notifications start to work properly

Alternative: I've tried to use `OneSignal.Notifications.requestPermission` instead of `PermissionsAndroid.request` assuming it might impact some internal logic of OneSignal and start to work, but it was even worse:
1. Install `react-native-onesignal` v5.0.1
2. Create `NotificationServiceExtension` for Android
3. Install & Launch the app 
4. Call `OneSignal.Notifications.requestPermission`
4.1. (optional - does not impact the result) Call OneSignal.login + Notifications.OptIn()
4.2. Call `getOptedIn` -> returns `TRUE` this time
5. `getPushSubscriptionId` and send it to backend for further REST API calls
6. Send push notifications to subscribed device via REST API from backend
AR: Push Notification are appeared `received` on app.onesignal dashboard, but `onNotificationReceived` is not firing at `NotificationServiceExtension`. Reopening of the app didn't help anyhow in this scenario

What did you expect to happen?

I expected that after updating to react-native-onesignal v5, push notifications on Android would continue to work as they did before the update.

React Native OneSignal SDK version

5.0.1

Which platform(s) are affected?

Relevant log output

No response

Code of Conduct

fmorau commented 9 months ago

Update:

Alternative described in Steps to reproduce? section where I've used OneSignal.Notifications.requestPermission - works.

So, it means, the issue is only in requesting permission not via OneSignal.Notifications.requestPermission. For example, in my case it is PermissionsAndroid.request from react-native library

nan-li commented 9 months ago

Hi @fmorau,

Thanks for the update to your question. That makes sense, the OneSignal SDK does not know when you request permissions outside of the SDK's methods, and won't read data until a new session.

We are looking into this as a feature to support.

fmorau commented 9 months ago

Hello @nan-li,

I hope you're doing well. I wanted to bring up an issue related to a functionality of this method and why I didn't use it.

I've encountered a situation where after selecting the "Refuse" option for push notifications permission, OneSignal.Notifications.requestPermission still returns a "true" result (which means Authorized). Additionally, trying to workaround it - I added check of OneSignal.Notifications.permissionNative afterward (due to unexpected results) - it solved this exact issue, but failed in another case, when I granted permission and checked OneSignal.Notifications.permissionNative, it still indicated a "Denied" status instead of "Authorized". It's been a bit frustrating to work through these issues, and I would greatly appreciate any insights or assistance you might have.

P.S. I could solve it for now by using third party permission check method after OneSignal.Notifications.requestPermission, but I assume you might want to fix it in upcoming releases

Thank you for your attention to this matter. πŸ™

fmorau commented 9 months ago

@nan-li I could solve the main issue described above by requesting permission via OneSignal.Notifications.requestPermission, but here is the case, which I could not "workaround"

  1. Download app & Open it
  2. Permission is requested after opening
  3. Deny notifications permission
  4. Go "In App" settings
  5. Enable notifications >> Modal to go to Phone app settings is shown
  6. User press a button to open settings, which executes Linking.openSettings (from react-native library)
  7. User Enables notifications in app settings and comes back P.S. After coming back -> OneSignal properly notifies about permission turned on, but the status of OneSignal.User.pushSubscription.getOptedIn still remains as false Even if OneSignal.User.pushSubscription.optIn is called
  8. User Receives a message

AR: No message is shown

After the app is reopened, all notifications appear (even for the message sent at step 8)

nan-li commented 9 months ago

Hi @fmorau, I apologize for the delay and thank you for the details.

I see there are 2 issues you are running into:

Question 1: This one I will investigate from our end and work on a fix, it seems for now you can workaround it.

I've encountered a situation where after selecting the "Refuse" option for push notifications permission, OneSignal.Notifications.requestPermission still returns a "true" result (which means Authorized). Additionally, trying to workaround it - I added check of OneSignal.Notifications.permissionNative afterward (due to unexpected results) - it solved this exact issue, but failed in another case, when I granted permission and checked OneSignal.Notifications.permissionNative, it still indicated a "Denied" status instead of "Authorized". It's been a bit frustrating to work through these issues, and I would greatly appreciate any insights or assistance you might have.

Question 2: The scenario you describe in the latest comment right above. I have some clarifying questions:

  1. Permission is requested after opening

You are calling OneSignal.Notifications.requestPermission to do this? And it is called early in the app launch process?

  1. Go "In App" settings
  2. Enable notifications >> Modal to go to Phone app settings is shown
  3. User press a button to open settings, which executes Linking.openSettings (from react-native library)

This is your own app settings page and how are you asking them to "Enable notifications"? Is it through a OneSignal method? Are there any calls to OneSignal in these steps?

  1. User Enables notifications in app settings and comes back P.S. After coming back -> OneSignal properly notifies about permission turned on, but the status of OneSignal.User.pushSubscription.getOptedIn still remains as false Even if OneSignal.User.pushSubscription.optIn is called

The OneSignal.Notifications.addEventListener("permissionChange", (observer) => {}) observer is triggered? Did you ever call OneSignal.User.pushSubscription.optOut()?

  1. User Receives a message

Sorry I misunderstand this. You send a message to the user but it is not shown on their device? And on the next app open, this notification is show by the device?

In the meantime, I think this is enough information for me to try and reproduce.

fmorau commented 9 months ago

Hello @nan-li ! No worries, and thank you for taking care of it πŸ™ I will try to answer your questions and if I will not be clear enough feel free to clarify.

  1. Yep, I could find a workaround using a combination of OneSignal.Notifications.requestPermission with custom permission check, so it's not blocking.

You are calling OneSignal.Notifications.requestPermission to do this? And it is called early in the app launch process?

Actually, in our case it happens long time after opening the app. User goes through sign-in / sign-up process until this method would be called.

This is your own app settings page and how are you asking them to "Enable notifications"? Is it through a OneSignal method? Are there any calls to OneSignal in these steps?

Yep, it is inside of our App. Whenever they want to enable/disable notifications we have specific "Settings" page for it. Whenever they try to turn it ON - we check programmatically if permission is granted on device level and if it is not - showing the modal (just react-native UI - not OneSignal method), which proposes to do it on device level first.

The OneSignal.Notifications.addEventListener("permissionChange", (observer) => {}) observer is triggered? Did you ever call OneSignal.User.pushSubscription.optOut()?

Yep, the subscription is triggered, when user returns back to the app, but getOptedIn still returns false even if optIn() call would be added No, we don't use OneSignal.User.pushSubscription.optOut() method

Sorry I misunderstand this. You send a message to the user but it is not shown on their device? And on the next app open, this notification is show by the device?

Oh, sorry, it's indeed might not be clear enough, 8. Send messages to the device via Backend should be more clear The thing is that these messages shown as "delivered" on OneSignal dashboard, but they will not be shown, until the app closed and opened back

nan-li commented 9 months ago

Hi @fmorau,

Sorry for the delay, I haven't been able to reproduce and then I was out of the office the previous week.

Here are the steps I took. I built in debug mode using a Nexus S emulator on API 33. I do not have any 'settings' page within the app.

  1. New installation of the app
  2. Call OneSignal.Notifications.requestPermission and DENY. I do see the incorrect true boolean you encountered and will look into this bug.
  3. Background the app and go to the native app settings, and choose to allow notifications. (I also tested killing the app instead of backgrounding the app)
  4. Open the app
  5. OneSignal.Notifications.addEventListener('permissionChange', listener) is triggered and returns true.
  6. OneSignal.User.pushSubscription.addEventListener('change', listener) is triggered and shows the optedIn property change from false to true.
    1. Send a notification to the device with the OneSignal Dashboard
    2. The notification is displayed on the device.
nan-li commented 9 months ago

Does this issue happen consistently on every Android device you tested?

nan-li commented 9 months ago

Following up on the other problem you encountered with using OneSignal.Notifications.requestPermission, I was not able to reproduce the issue if permission is ACCEPTED using this method.

When I call OneSignal.Notifications.requestPermission, the native prompt displays and I choose to accept the permission.

I did not use other notification permission prompting methods.

fmorau commented 8 months ago

Hello @nan-li,

Thank you for addressing this!

In response to your comment:

"I do not have any 'settings' page within the app."

I'd like to clarify the steps:

  1. Navigate to the "In App" settings.
  2. Enable notifications, which triggers a modal to open the Phone app settings.
  3. When the user presses a button to open settings, it executes Linking.openSettings from the React Native library.

In essence, this means that the user triggers a Linking.openSettings call, which opens the App Settings. You can simply add a button with a handler that calls Linking.openSettings.

Regarding the consistency of this issue on Android devices - it occurs consistently on every Android device we've tested.

nan-li commented 8 months ago

Hmm, ok maybe there is something strange with using Linking.openSettings and OneSignal is not detecting something. I wouldn't think so, but I'll test using that method.

Also I am curious what happens if you don't use Linking.openSettings... just go to native app settings directly and enable or disable the notification permission. Then, return to the app...?

^ Are the correct observers triggered and behavior is correct? Or behavior is still wrong, and same as using Linking.openSettings?

Thank you for following up with your details all this time. It is appreciated.

fmorau commented 8 months ago

Hello, @nan-li!

I've recently updated react-native-onesignal in our app to the latest v5.0.3 with the fix you've made, I retested all cases, and it worked very well! Even with Linking.openSettings and going back to the app after granting notifications permission - all worked! I've received permission change event and all data from OneSignal SDK were relevant πŸ‘ Thank you for your involvement and congratulations for the great job you are guys doing!

Looks like we can close the issue now, Merci beaucoup!

fmorau commented 8 months ago

But looks like I faced another one, one lever higher:

When I played further with turn on / off permissions and then open the app back to check if subscription and statuses are working well - it was indicating everything properly, But.... after enabling notifications and from inside the app it all looked good, inside my OneSignal app, I've seen this device with "permission not granted" label And messages were not coming πŸ˜”

@nan-li

nan-li commented 8 months ago

Hi @fmorau,

When I played further with turn on / off permissions and then open the app back to check if subscription and statuses are working well - it was indicating everything properly, But.... after enabling notifications and from inside the app it all looked good, inside my OneSignal app, I've seen this device with "permission not granted" label And messages were not coming πŸ˜”

Can you explain more details?

In the app, it looks like the behavior is correct?... calling OneSignal methods like hasPermission() and permissionNative looks correct, the observers are triggering correctly?

But in the OneSignal dashboard, you see the subscription with the "Permission Not Granted"?

Can you reproduce your steps?

Screenshot 2023-11-16 at 4 38 26 PM

fmorau commented 8 months ago

@nan-li yep, exactly! And even sometimes after I close and then open the app it still "Not Granted" and then with a couple more tries to close & open the state it suddenly changes

fmorau commented 8 months ago

@nan-li should I log it somewhere as separate Issue, or you have already initiated process on it from within OneSignal Team?

nusendra commented 7 months ago

I'm having getPushSubscriptionId issues. It seems need to await for response. Because when i want to get the subs id, its just empty.

const deviceId = OneSignal.User.pushSubscription.getPushSubscriptionId();
console.log(deviceId); // this print nothing
nan-li commented 6 months ago

Hi @fmorau I am so sorry for the delay.

I haven't been able to reproduce your new issue yet with toggling permission on and off outside of the application.

Do you happen to have logs to share? The Dashboard will show "Permission Not Grated" after the SDK tells the server that there is no permission. That means somehow, the SDK sent a request to the server with that information. All requests should be logged.

nan-li commented 6 months ago

Hi @nusendra,

Sorry for the confusion.. The await exists because we have to call into native Android methods to find the value, and it is not for waiting for the push subscription ID to be retrieved.

You can use the push subscription observer to be notified when it is retrieved. See usage for Push Subscription Observer in the migration guide here.

nusendra commented 6 months ago

Hi @nusendra,

Sorry for the confusion.. The await exists because we have to call into native Android methods to find the value, and it is not for waiting for the push subscription ID to be retrieved.

You can use the push subscription observer to be notified when it is retrieved. See usage const deviceId = OneSignal.User.pushSubscription.getPushSubscriptionId(); console.log(deviceId); // this print nothing.

I see, thanks. i will update my code later. Currently im using this solution https://github.com/OneSignal/react-native-onesignal/issues/1616

nan-li commented 6 months ago

I see, also apologies I did not write my response correctly. I just updated my comment to use the correct link @nusendra

nusendra commented 6 months ago

I see, also apologies I did not write my response correctly. I just updated my comment to use the correct link @nusendra

i believe i did that way before, but somehow it didn't work. But thanks, i'll try again. Maybe im missing something