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
- 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 = { ... },
)
- Tap "Sign in with Google".
- 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.
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:
-
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.
-
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.
Environment
com.firebaseui:firebase-ui-auth:10.0.0-beta03(ComposeFirebaseAuthScreen)Steps to reproduce
FirebaseAuthScreenwith a Google provider:Observed
An "Authentication Error" dialog appears:
GetCredentialCancellationExceptionmessage rendered as button text.onSignInCancelledis never invoked.Expected
Cancelling a sign-in is a normal user action, not an error. Expected the flow to return
to the method picker silently, with
onSignInCancelledinvoked — i.e. the existingAuthState.Cancelledpath, which already does exactly this and shows no dialog.Analysis
Two separate problems compound here:
Cancellation is routed to the error state. In
GoogleAuthProvider+FirebaseAuthUI.kt(~line 217), theCancellationExceptionfrom thecredential flow is caught and re-emitted as
updateAuthState(AuthState.Error(AuthCancelledException(...)))rather than
AuthState.Cancelled. The top-level dialog controller inFirebaseAuthScreenthen unconditionally shows
ErrorRecoveryDialogfor anyAuthState.Error.The raw exception message is used as the button label. In
ErrorRecoveryDialog.kt,getRecoveryActionText()mapsAuthCancelledException -> 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), nevererror.message.Suggested fix: emit
AuthState.Cancelledfor user-initiated cancellations in the Googleprovider (matching the documented behavior of
AuthCancelledException: "thrown when theuser cancels an authentication flow"), and stop using
error.messageas an action label inErrorRecoveryDialog.