signOut method

  1. @override
Future<Either<AuthServiceSignOutFailure, Unit>> signOut({
  1. bool useFbAuthAlso = true,
})
override

Implementation

@override
Future<Either<AuthServiceSignOutFailure, Unit>> signOut({bool useFbAuthAlso = true}) async {
  // Clear cached auth state immediately
  _updateCachedState(false);

  // Cancel any pending completers
  if (_loginCheckCompleter != null && !_loginCheckCompleter!.isCompleted) {
    _safeCompleteLoginCheckWithError('User signed out');
  }

  // ...existing signOut code...
  try {
    // Call all onAboutToLogOut callbacks while still authenticated (before Firebase signOut)
    // This allows cleanup tasks like FCM token unregistration that require auth
    if (useFbAuthAlso && _onAboutToLogOutByPriority.isNotEmpty) {
      final timeout = Duration(milliseconds: AppConfigBase.timeoutForAboutToLogOutCallbackMill);
      await _executeVoidCallbacksByPriority(
        _onAboutToLogOutByPriority,
        timeout,
        'onAboutToLogOut',
      );
    }

    if (useFbAuthAlso) {
      await _fbAuth.signOut();
    }

    // Call all onLoggedOut callbacks (after sign out is complete)
    // Using a generous timeout for post-logout callbacks
    await _executeVoidCallbacksByPriority(
      _onLoggedOutByPriority,
      const Duration(seconds: 30),
      'onLoggedOut',
    );

    // Clear the cookie on the server if using federated auth
    if (AppConfigBase.useCookieFederatedAuth) {
      final http.Client client = http.Client();

      final response = await client
          .get(Uri.parse(RepoHelpers.getFunctionUrl(_fbAuth.app, 'authfunctions-signout')));

      if (response.statusCode == 204) {
        logd('Cleared cookie successfully');
      } else {
        logd('Failed to clear cookie!!');
        // Don't return error for cookie clear failure
      }
    }

    // Clear any legacy stored user info
    SharedPreferences prefs = await SharedPreferences.getInstance();

    // MIGRATION NOTE: This key was never actively written to, but we keep the
    // removal call for safety during migration. Device-level cleanup (including
    // timezone data) is now handled by DeviceService.unregisterDevice() which
    // is automatically called via the onAboutToLogOut callback when
    // DeviceService.connectToAuthService() has been configured.
    // TODO(migration): Remove this line after confirming no production data
    // uses this key (target: next major version after v0.4.0).
    // ignore: deprecated_member_use_from_same_package
    await prefs.remove(sharedPrefKeyTimezone);

    // Note: FCM token cleanup has been moved to NotificationService.clearFcmToken()
    // Apps should call NotificationService.clearFcmToken() before signing out.

    _accessCodeCached = null;
  } on fb_auth.FirebaseAuthException catch (e) {
    loge(e);
    return left(AuthServiceSignOutFailure.unexpected);
  } catch (e) {
    loge(e);
    return left(AuthServiceSignOutFailure.unexpected);
  }

  return right(unit);
}