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

[Bug]: optIn() and optOut() seem like they should return a promise that one can await #967

Open
3 tasks done
kpturner opened this issue Jan 27, 2024 · 5 comments
Open
3 tasks done

Comments

@kpturner
Copy link

kpturner commented Jan 27, 2024

What happened?

Both the optIn and optOpt methods do not return anything and do not appear to be async. However, surely under the covers both are making an async communication with the OneSignal backend? This being so, it is not possible to await the outcome. It is possible to do lots of optIn and optOut calls in a client app and not really know what the final outcome is, because there is no guarantee that the updates to the backend will be processed in the order that you executed them. For example, I could call optIn and optOut one after the other but the optIn request might be processed after the optOut. So the app thinks it is opted out when in fact it is not.

This is the only explanation I can think of for the situation we have where the "opted in" status in OneSignal does not always match the last status update the app thinks it sent.

Why can we not await each of these calls so that we know that it has been received and processed?

Steps to reproduce?

Described above

What did you expect to happen?

I would expect all methods that perform async requests to the OneSignal backend to return a promise that can be awaited.

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
@nan-li
Copy link
Contributor

nan-li commented Jan 29, 2024

Hi @kpturner, thanks for your question and I understand your feature request.

The reason we don't have a callback to optIn and optOut is that the SDK batches requests and sends them in 5 second intervals, and uses caching and retries. There are not 2 requests made for the 2 actions, but rather 1 request with the latest state.

For example, I could call optIn and optOut one after the other but the optIn request might be processed after the optOut. So the app thinks it is opted out when in fact it is not.

If you call optIn and optOut one after the other, what happens depends on if optIn resulted in any user action, but let's say the user has already given permission and optIn and optOut are just flags to turn on and off the notifications.

When optIn is called, we set local state to "true" and then when optOut is called, we set local state to "false". Then when it is time to send the batched requests, the latest state is sent, so "false" is sent. If the device is offline or the SDK receives a 500 error, it will cache and retry the request again.

So, it is not trivial to return promises to these methods. In the scenario with the 2 calls back to back, what should be returned to the first optIn call if we ultimately send only the optOut call.

@kpturner
Copy link
Author

kpturner commented Jan 29, 2024

Hel @nan-li

Thankyou for that explanation of what is going on under the covers. Then the explanation for what is causing a mismatch between what the app thinks the opt-in status is and what is showing on the dashboard may lay elsewhere.

Firstly it seems likely therefore that calling optIn may not result in the dashboard showing opted-in because the request has simply not been sent yet. But then that begs the question, why is the optedIn method asynchronous? Is it fetching the latest state as it shows in the dashboard or is it fetching the local state? Where is the local state stored?

If I start the app and call initialize() then I await optedIn() it doesn't give me the correct answer. It returns false even though it might really be true. I might then have a load of logic around the fact that the user is opted-out even though they might actually be opted-in. Is this the sort of thing that will be sorted when we can await initialize in order to be sure that any info fetched from the bridge will be accurate?

Can I assume also that as optIn is supposed to behave like requestPermission? Should it also have a fallbackToSettings boolean parameter?

@kpturner
Copy link
Author

kpturner commented Feb 5, 2024

When and how does the app decide to send the batch updates? I have called optedIn and waited some 20 minutes and the dashboard still shows opted out. What if the app is terminated before the batch of updates is sent (for example)? Does it still happen in the background?

@kpturner
Copy link
Author

kpturner commented Feb 5, 2024

Example. Sent the optedIn request. The event regarding the subscription change shows optedIn as true. The dashboard still says its opted out.

image

image

@kpturner
Copy link
Author

kpturner commented Feb 5, 2024

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.

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

2 participants