Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feedback]: notification permission API confusion #2184

Open
1 task done
KChernenko opened this issue Aug 27, 2024 · 8 comments
Open
1 task done

[Feedback]: notification permission API confusion #2184

KChernenko opened this issue Aug 27, 2024 · 8 comments

Comments

@KChernenko
Copy link

KChernenko commented Aug 27, 2024

What's on your mind?

SDK's API is highly confusing when dealing with the system notifications permission flow.
We're a significant client with tens of millions of installs and several millions of MAU. We want to show our custom screen that explains why we need notification permission and request this permission ourselves. Later, after the user onboarding process, we engage them using your service. With your SDK, after years of being your customer, we're still trying to figure out how to achieve this. In the documentation, you're saying that in order to turn off internal system notifications permission request, we need after the

OneSignal.initWithContext(this, ONESIGNAL_APP_ID)

Call (by the way, why is it a suspended function?)

CoroutineScope(Dispatchers.IO).launch {
         OneSignal.Notifications.requestPermission(false)
      }

However, in the migration guide, you're mentioning:

To resume receiving of push notifications (driving the native permission prompt if OS permissions are not available), you can opt back in:

pushSubscription.optIn()

And its conterpart:

If at any point you want the user to stop receiving push notifications on the current device (regardless of Android permission status) you can use the push subscription to opt out:

pushSubscription.optOut()

Do we need to call optIn() right after the SDK initialization? If yes, should OneSignal.Notifications.requestPermission(false) be called after or before the optIn()? We tried both ways, and in either case, an internal system notifications permission request is executed, and a permission dialog shows up in the places we do not want. We tried to call optIn() in the OneSignal.Notifications.addPermissionObserver:

OneSignal.Notifications.addPermissionObserver(object: IPermissionObserver {
                override fun onNotificationPermissionChange(permission: Boolean) {
                    println("Permission triggered, OneSignal opt in: $permission")
                    if (permission) {
                        OneSignal.InAppMessages.paused = false
                        OneSignal.User.pushSubscription.optIn()
                    } else {
                        OneSignal.InAppMessages.paused = true
                        OneSignal.User.pushSubscription.optOut()
                    }
                }
            })

The callback is triggered only when permission is enabled. When we disable the permission in the system setting (Android 14), we do not receive the onNotificationPermissionChange, so the optOut() call is not executed.
It is extremely important for us to provide a smooth and legal complaint flow for our users, but currently, we can not do this due to an unknown reason (it's a bug, multiple bugs, not clear documentation, or both?).

Code of Conduct

  • I agree to follow this project's Code of Conduct
@jkasten2
Copy link
Member

jkasten2 commented Aug 28, 2024

@KChernenko thanks for the feedback, I'll expand a bit more on requestPermission() and optIn() / optOut() here to hopefully clear things up.

optIn & optOut

Usage Cases

Use these if you want to have an option were end-users can turn off OneSignal push notifications inside your app.

Description

Call optIn() to enable OneSignal push notifications for the user. Call this after after your custom screen explaining what notifications will be shown.

  • On Android 13 and newer this will automatically show the native Android notification permission dialog.
  • If the user disabled notifications at the Android Operating System level, this will show a OneSignal dialog telling them how to turn them back on in the settings.

Additional Considerations

Note OneSignal SDK keeps track of which was called last optedIn() or optOut() as a preference for the user. If optOut() was called then the SDK uses this over the Android Operating System Notification permission.

requestPermission

requestPermissio() call this if you want to show the notification prompt. If the end-user accepts, they will be subscribed for OneSignal push notifications.

  • optOut() is still respected, so it won't change that subscribed status in this case.
  • If optIn and optOut cover all your use cases you can ignore requestPermission().

onNotificationPermissionChange

The callback is triggered only when permission is enabled. When we disable the permission in the system setting (Android 14), we do not receive the onNotificationPermissionChange...

It should fire in both cases, as long as you foreground the app after you change the setting. If you are using an older SDK than OneSignal-Android-SDK 5.1.15 please update, s there was a bug in older versions. If you can still reproduce on the latest version can you share details on how you reproduce the issue?

  • If onNotificationPermissionChange isn't firing due to a bug, then the subscribed status might not be updating automatically either.

Also I won't recommend calling optOu() from onNotificationPermissionChange like you have in your code above. You may also want to consider if want to call optIn() either from there, it will override a previous call to optOut().

While your questions here are the right place to ask them at your scale you may want to reach out to OneSignal support for faster support.

@michael-winkler
Copy link

@jkasten2
Another question too:

When can we call as example OneSignal.login("max.mustermann") ?

Is the nofitication permission required for that or can we call the login at any time?

Also what happens if we call OneSignal.logout() if there was never a OneSignal.login("max.mustermann") ?

@jkasten2
Copy link
Member

@michael-winkler

When can we call as example OneSignal.login("max.mustermann") ?

Is the nofitication permission required for that or can we call the login at any time?

You can call login() anytime after initWithContext(). Everything works as expected without notification permission, you can add / remove tags, set language, ect and they will all be send to OneSignal and will show on the OneSignal dashboard.

Also what happens if we call OneSignal.logout() if there was never a OneSignal.login("max.mustermann") ?

Repeated calls to logout() does nothing (or if you never called login()).

@michael-winkler
Copy link

Thanks for the answer.
And a last question.

How can I call initWithContext when I change the ID?

Example: In my app, I can switch between a test system and a live system. Both systems have a different OneSignal App ID.

Do I need to perform a logout first when switching systems, or what is the best approach to handle this?

@jkasten2
Copy link
Member

@michael-winkler changing the appId isn't support in the SDK. If you need to change the value for you testing you must clear all data for your app in the Android settings, or uninstall and reinstall the app.

@michael-winkler
Copy link

michael-winkler commented Aug 29, 2024

Is there a possibility that you could integrate something like this into the SDK?

It would be great if you could add this as a feature.

This was also asked by another user:

#2169

This leads to another question.

Example: I have a successful subscription.

Now, I completely clear the app's cache. I log in again with my old external User ID.

Will everything work as before and be restored?

@michael-winkler
Copy link

@jkasten2 Can you please give here again an answer? 😄

@jkasten2
Copy link
Member

jkasten2 commented Sep 5, 2024

Is there a possibility that you could integrate something like this into the SDK?

It would be great if you could add this as a feature.

This was also asked by another user:
#2169

The SDK wasn't designed for the appId to change, just about every part of the SDK depends on it.

Could you explain your use case?

This leads to another question.

Example: I have a successful subscription.

Now, I completely clear the app's cache. I log in again with my old external User ID.

Will everything work as before and be restored?

Clearing the app's cache won't affect this, only clearing the app's data will. It behaves just like uninstalling and reinstall the app. If you login to the same external User ID the SDK will recover the User, however since the data was cleared it will created a new push subscription.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants