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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bug]: Inconsistent behavior with `Notifications.requestPermission(true)` when user prompted to change settings

kpturner opened this issue · comments

What happened?

If I call Notifications.requestPermission(true) on iOS or Android 13, and the call deems that it is necessary to prompt the user, two things happen:

  1. It prompts for permission or
  2. If 1) has already been previously prompted, it will prompt the user to change their settings

If 2) takes place, then the call to the function exits as soon as the user clicks the "Settings" button and returns false - so you do not actually know if the user allowed notifications in their settings or not.

On Android 12, the function does not exit when the user clicks "Settings". In fact it does not return until the user has visited their settings, changed them and then return control to the app. At that point the function exits, but always returns false regardless of what the user did.

So it seems impossible to know if the user has allowed notifications in their settings or not after calling requestPermission(true)

With Android 13 and iOS you can at least have a listener on the permissionChange event which fires when the user changes the permission in the settings. The same does not work with Android 12. The event does fire (seemingly inconsistently) but provides completely the wrong value - always false even though permission has been granted.

Steps to reproduce?

Described above

What did you expect to happen?

I expect Android 12 and 13 and iOS to behave consistently.

Ideally, the requestPermission(true) call would only return when the user has changed their settings, and will provide the correct value.

Also, the permissionChange event should fire consistently in Android 12 and provide the correct value.

OneSignal Cordova SDK version

5.0.4

Which platform(s) are affected?

  • iOS
  • Android

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

I can confirm this behaviour. I am not even able to subscribe anymore on Android, it always unsubscribes when calling optIn() or requestPermission()

I can confirm this behaviour. I am not even able to subscribe anymore on Android, it always unsubscribes when calling optIn() or requestPermission()

When you say it unsubscribes you, do you mean that your subscription disappears from the dashboard or it gets flagged as "opted-out"? Is this Android 12 or 13 by the way?

It unsubscribes every time, i tested android 13 (sdk 33) only.

It updates the timestamp of 'Last unsubscribed' every time i call requestPermission(true) or requestPermission() or optIn(). Very annoing.
image

It only shows "Permission not granted" when i uninstall the app, install it and call requestPermission(true), then deny it.

Have you called login()?

What login function?
OneSignal.???.login() ?

Yes I am just trying to see if I can match those symptoms (which seem even more buggy than the ones I reported) but my sequence of events is:
OneSignal.initialize()
OneSignal.login()
and then, if I somehow managed to find out if the user has granted permission or not
OneSignal.User.pushSubscription.optIn()

But if I can get the same result as you then things are even worse than I reported here.

As an aside, you should be aware of this issue too: #918
which renders most of the functions (that should be async and are not) to return incorrect values when the app starts (which is often when you most need them):
OneSignal.User.pushSubscription.optedIn
OneSignal.User.pushSubscription.id
OneSignal.Notifications.hasPermission
and add this in for good measure: #967

But that aside, when I do this

OneSignal.initialize()
OneSignal.login()
OneSignal.User.pushSubscription.optIn()

I do end up with this, but it takes quite a while to update correctly in the dashboard
image

commented

Hi @kpturner, thank you for reporting, I was able to reproduce the behavior with calling requestPermission() in combination with the Settings prompt.

We will investigate a solution.

commented

Hi @louis123562, can you tell me more about your issue?

When you prompt for permission but before a choice is made, the SDK may believe permission is not granted yet and send an update to the server causing the "Last Unsubscribed" date to be updated on the dashboard. (This is related to the issue reported by @kpturner that we will investigate.) Then when a choice is made on the permission prompt, a subsequent request is sent with that selection.

Are you seeing it does not update in the dashboard after you give permission in the permission prompt?

Just top be clear on the Android 12 situation: If you are prompted to change your settings, even if you allow them, hasPermission will continue to return false until you restart the app. It is an absolute nightmare!

Hi @louis123562, can you tell me more about your issue?

When you prompt for permission but before a choice is made, the SDK may believe permission is not granted yet and send an update to the server causing the "Last Unsubscribed" date to be updated on the dashboard. (This is related to the issue reported by @kpturner that we will investigate.) Then when a choice is made on the permission prompt, a subsequent request is sent with that selection.

Are you seeing it does not update in the dashboard after you give permission in the permission prompt?

I just tested on Android 14, it behaves the same as Android 13.

When removing permission manually in Android settings, then going back into the app, call requestPermission(true), the dialog comes up. If i then look at the OneSignal dashboard, it says "Permission Not Granted" with the current timestamp; so it was updated when the dialog came up.

After accepting to receive notifications in the dialog, the Subscriptions Status is empty, and the Last Subscribed is set with the timestamp when touch "accept" in the dialog. Weird!

Calling optIn() at any time has no effect at all.

This also behaves the same, if the app is reinstalled and/or permissions where not granted yet. For my understanding, it is currently not possible to get any Android to subscribe. All my Android subscriptions either have the Subscription Status empty with a Last Unsubscribed timestamp, or Permission not Granted.

This is not great. With this, i am not able to reach any of my android users.

@louis123562 it is worth noting that apparently optIn does not update the dashboard straight away. It updates a flag locally straight away, but the requests to the OneSignal dashboard (server) are batched up and sent periodically. I am not sure what triggers them to be sent but it is not immediate. Obviously this does not explain your scenario though.

I think @louis123562 is possibly experiencing the same issue as I describe here: #967

I can call optIn over an over again and yet the date last unsubscribed data on the dashboard is the only thing that changes, and it still shows "User Opted Out"

I have no idea how to actually get it to regsiter that the user is opted in - or why it thinks the subscription is unsubscribed :(

EDIT: I finally made it work by disallowing notifications on the device, then calling optIn which prompted me to allow notifications and THEN it updated the dashboard correctly.