Skip to content

Cancelling the Google sign-in sheet shows an error dialog with the raw exception message as button text (expected AuthState.Cancelled, no dialog) #2422

Description

@joknu1

Environment

  • FirebaseUI version: com.firebaseui:firebase-ui-auth:10.0.0-beta03 (Compose FirebaseAuthScreen)
  • Device: OnePlus 10 Pro (NE2213), Android 16 (API 36)
  • Google Play services: 26.26.34

Steps to reproduce

  1. Configure FirebaseAuthScreen with a Google provider:
FirebaseAuthScreen(
    configuration = authUIConfiguration {
        this.context = context
        isCredentialManagerEnabled = false
        isMfaEnabled = false
        providers {
            provider(AuthProvider.Google(scopes = emptyList(), serverClientId = webClientId))
            provider(AuthProvider.Facebook())
            provider(AuthProvider.Email(emailLinkActionCodeSettings = null, passwordValidationRules = emptyList()))
        }
    },
    onSignInSuccess = { ... },
    onSignInFailure = { ... },
    onSignInCancelled = { ... },
)
  1. Tap "Sign in with Google".
  2. Dismiss the Credential Manager account sheet (swipe back / tap outside).

Observed

An "Authentication Error" dialog appears:

  • Message: "Authentication was cancelled. Please try again when ready."
  • Confirm button labeled "User cancelled the selector" — the raw
    GetCredentialCancellationException message rendered as button text.
  • onSignInCancelled is never invoked.
Image

Expected

Cancelling a sign-in is a normal user action, not an error. Expected the flow to return
to the method picker silently, with onSignInCancelled invoked — i.e. the existing
AuthState.Cancelled path, which already does exactly this and shows no dialog.

Analysis

Two separate problems compound here:

  1. Cancellation is routed to the error state. In
    GoogleAuthProvider+FirebaseAuthUI.kt (~line 217), the CancellationException from the
    credential flow is caught and re-emitted as updateAuthState(AuthState.Error(AuthCancelledException(...)))
    rather than AuthState.Cancelled. The top-level dialog controller in FirebaseAuthScreen
    then unconditionally shows ErrorRecoveryDialog for any AuthState.Error.

  2. The raw exception message is used as the button label. In ErrorRecoveryDialog.kt,
    getRecoveryActionText() maps AuthCancelledException -> error.message ?: stringProvider.continueText,
    so whatever message the underlying exception carries ("User cancelled the selector")
    becomes the confirm-button text. Even for genuine error cases this should presumably be
    stringProvider.continueText (or another localized action label), never error.message.

Suggested fix: emit AuthState.Cancelled for user-initiated cancellations in the Google
provider (matching the documented behavior of AuthCancelledException: "thrown when the
user cancels an authentication flow"), and stop using error.message as an action label in
ErrorRecoveryDialog.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions