Skip to content

fix: make logout() awaitable on both platforms — resolve when the session actually ends - #98

Closed
airowe wants to merge 1 commit into
frontegg:masterfrom
airowe:fix/ios-awaitable-logout
Closed

fix: make logout() awaitable on both platforms — resolve when the session actually ends#98
airowe wants to merge 1 commit into
frontegg:masterfrom
airowe:fix/ios-awaitable-logout

Conversation

@airowe

@airowe airowe commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Problem

logout() is fire-and-forget on both platforms: the iOS bridge calls auth.logout() without the completion overload, and the Android bridge ignores the SDK's callback parameter. JS has no way to know when the session has actually ended and must rely solely on the auth-state event — which can be lost when logout coincides with app-level teardown (see #97 for the event-delivery half of this). The observed failure mode on-device: JS state stays authenticated forever after a logout, and the next login's state-transition detection never fires.

Both native SDKs already expose exactly the hook needed — iOS FronteggAuth.logout(_ completion:), Android logout(callback: () -> Unit) — the bridge just doesn't use them. login() is already awaitable; logout() should be too.

ios-logout-relogin-green.mp4

Fix

  • iOS: promise-based bridge method using the completion overload; pushes the final auth state to JS (on main, respecting RCTEventEmitter's threading of hasListeners/pendingObservingState) before resolving. DispatchQueue.main.syncasync (you can't block main waiting for an async completion).
  • Android: fun logout(promise: Promise) resolving from the SDK callback.
  • JS: logout() typed Promise<void>.

Compatibility

export function logout() already returns the bridge call, so existing callers that ignore the return value are unaffected; callers can now await it. The iOS completion is success-only, so there is no reject path.

Validation

Running in production QA via patch-package (iOS half) since June across a 50-target workspace: app-level logout flows await logout() and then tear down safely, with the final state event guaranteed delivered first. Android change compiles against com.frontegg.sdk:android 1.3.35 (callback parameter has a default, so the SDK call is source-compatible).

…sion actually ends

The bridge logout was fire-and-forget on both platforms: iOS called
auth.logout() without the completion overload; Android ignored the SDK's
callback parameter. JS had no way to know when the session was actually
gone and relied solely on the auth-state event — which can be lost when
logout coincides with app-level teardown, leaving the JS state
authenticated forever and breaking the next login's state-transition
detection (observed on-device).

Both native SDKs already expose completion callbacks (iOS
FronteggAuth.logout(_ completion:), Android logout(callback:)); the
bridge just didn't use them. logout() now returns a Promise that
resolves when the native SDK reports completion, and iOS pushes the
final auth state to JS before resolving. The JS export is typed
Promise<void>. Existing callers that ignore the return value are
unaffected.
@dianaKhortiuk-frontegg

Copy link
Copy Markdown
Collaborator

Superseded by #101 — closing to avoid a redundant/conflicting merge.

#101 is built on this commit, so it carries this exact awaitable-logout() change on both platforms, and adds a 10s timeout fallback + a resolve-once guard so await logout() always settles even if the native completion callback never fires. The fix you made here ships there — nothing is lost.

Thanks @airowe 🙏

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

Successfully merging this pull request may close these issues.

2 participants