-
Notifications
You must be signed in to change notification settings - Fork 218
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
[fix] Android: Resolve requestPermission
call when already granted
#806
Conversation
93542a2
to
e9e82b1
Compare
I rebased my branch to make the commit history neater. You might need to rebase this PR too I think this bug applies to all wrappers. If so, do you think this logic should be replicated in each wrapper or could we have logic in the native Android SDK? |
Yes that would be ideal, I haven't found a way to workaround this yet. The problem arises from this method being implemented in Kotlin using coroutines. If you are using Kotlin, it just works and returns the boolean directly and correctly. If you are using Java to call the method, you must use a Continuation block. Users of the native SDK likely won't run into their app hanging because they are unlikely to put additional logic in the block. Users of our wrappers are likely to use async await with this method which will cause their app to hang. For example: // kotlin
var permission = OneSignal.Notifications.requestPermission(true); // java
OneSignal.getNotifications().requestPermission(true, Continue.with(r -> {
// code to execute using the response, unlikely app developers have blocking code within here
})); |
Problem: If permission is already enabled, the native call to `OneSignal.getNotifications().requestPermission(fallbackToSettings, Continue.with(...)` never suspends and the Continuation code block never runs. As a result, we would not be able to resolve the promise over the bridge. Solution: Before calling that method, do a permission check and return true. Opt to check the permission in Android instead of resolving early in Dart because the permission boolean may not be initialized correctly yet when requestPermission is called soon after initialization.
b0bbd6c
to
58e4661
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 1 files at r1, all commit messages.
Reviewable status: complete! all files reviewed, all discussions resolved (waiting on @emawby, @jennantilla, and @jinliu9508)
Do you know if this also applies to Location.requestPermission? |
It doesn't apply to Location.requestPermission currently because we do not give back the users's selection to this prompt. |
Why is waiting for ? |
Big thanks to @nan-li and the OneSignal Team for the rapid response and fixing the issue in Release 5.1.0 :) |
[fix] Android: Resolve `requestPermission` call when already granted
Description
One Line Summary
Resolve
requestPermission
call if permission is already granted.Details
Problem:
If permission is already enabled, the native call to
OneSignal.getNotifications().requestPermission(fallbackToSettings, Continue.with(...)
never suspends and the Continuation code block never runs. As a result, we would not be able to resolve the promise over the bridge.Solution:
Before calling that method, do a permission check and return true.
I chose to check the permission in Android bridge instead of resolving early in Dart because the Dart-level
_permission
boolean may not be set yet whenrequestPermission
is called soon after initialization. I ran into this case when testing the following scenario:Test scenario
Motivation
Resolve calls to request permission correctly so app code doesn't hang.
A customer reached out to support.
Scope
Now, we also resolve correctly when permission has already been granted.
Testing
Unit testing
None
Manual testing
Android emulator API 33
Affected code checklist
Checklist
Overview
Testing
Final pass
This change is