Skip to content

fix(auth): stop showing error dialog when Google sign-in is cancelled - #2427

Open
demolaf wants to merge 1 commit into
version-10.0.0-beta04from
fix/2422-google-signin-cancel
Open

fix(auth): stop showing error dialog when Google sign-in is cancelled#2427
demolaf wants to merge 1 commit into
version-10.0.0-beta04from
fix/2422-google-signin-cancel

Conversation

@demolaf

@demolaf demolaf commented Jul 27, 2026

Copy link
Copy Markdown
Member

Fixes #2422.

Cancelling the Google sign-in Credential Manager sheet showed an "Authentication Error" dialog with the raw GetCredentialCancellationException message ("User cancelled the selector") as the button text, instead of returning silently via AuthState.Cancelled. signInWithGoogle only caught kotlinx.coroutines.CancellationException, not the actual exception Credential Manager throws on dismissal, so it fell through to the generic error path.

  • GoogleAuthProvider+FirebaseAuthUI.kt: catches GetCredentialCancellationException explicitly and updates AuthState.Cancelled without rethrowing, so the sign-in flow returns to the picker silently and onSignInCancelled fires.
  • ErrorRecoveryDialog.kt: getRecoveryActionText no longer uses the raw exception message as the button label for AuthCancelledException.

Added a test covering the Credential Manager cancellation path, and fixed ErrorRecoveryDialogLogicTest to exercise the real (now-internal) dialog logic functions instead of a stale duplicate that had drifted from the actual code.

Preview

no-cancel-dialog.webm

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds handling for GetCredentialCancellationException when a user dismisses the Credential Manager sheet during Google Sign-In, updating the authentication state to AuthState.Cancelled without throwing an exception. It also changes the visibility of getRecoveryMessage, getRecoveryActionText, and isRecoverable in ErrorRecoveryDialog.kt from private to internal, enabling direct testing and the removal of redundant helper methods in ErrorRecoveryDialogLogicTest.kt. There are no review comments, and I have no feedback to provide.

@russellwheatley russellwheatley left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One concern on where sheet dismiss lands in the state machine.

// not an error, so it goes to AuthState.Cancelled instead of AuthState.Error.
// Swallow (don't rethrow) so rememberGoogleSignInHandler's catch block doesn't
// overwrite this state with AuthState.Error.
updateAuthState(AuthState.Cancelled)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Routing sheet dismiss to AuthState.Cancelled fixes the Compose path (no dialog, onSignInCancelled fires), but FirebaseAuthActivity finishes with RESULT_CANCELED on that state. So Activity / AuthFlowController consumers would leave the whole auth UI when the user just dismisses the Google sheet, rather than staying on the method picker.

Is that intentional? If those consumers should stay on the picker, this probably wants Idle (or similar) instead of Cancelled, and onSignInCancelled would need a different trigger for provider-level dismiss.

@demolaf demolaf Aug 5, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a gap in the implementation, the AuthFlowController.cancel triggers AuthState.Cancelled and terminates the entire activity which means AuthState.Cancelled is doing multiple things.

Using AuthState.Idle doesn't convey that an operation was cancelled, so that's ruled out.

We can leave AuthState.Cancelled for when an operation is cancelled and introduce a new state e.g. AuthState.Finished for when AuthFlowController.cancel is invoked?

This would be a breaking change.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it would be a breaking change in behaviour, but Cancelled is doing two jobs. So I think we have to split it out. Here is what it should look like:

Cancelled cancels the current step within the flow (provider sheet dismissed, MFA challenge backed out of) and returns to the picker.
Aborted (new) aborts the entire flow, triggered by AuthFlowController.cancel(), and finishes the activity.
Went with Aborted over Finished, reads too close to Success in my opinion.

Another thing: Cancelled isn't just consumed in FirebaseAuthActivity, it's also handled in FirebaseAuthScreen, PhoneAuthScreen, and EmailAuthScreen. AuthState isn't sealed, so none of those will fail to compile if we forget to add the matching Aborted branch, they'll just silently no-op. Worth a test per call site rather than relying on the compiler to catch it.

Also, MFA-challenge-cancel currently routes through Cancelled too, so today it already finishes the whole activity via that same listener. After the split it'll correctly stay in the flow instead, that's a behavior change that should have its own test, not just a side effect.

@demolaf
demolaf force-pushed the fix/2422-google-signin-cancel branch 2 times, most recently from d6ba147 to 0c191b4 Compare August 6, 2026 11:57
@demolaf
demolaf changed the base branch from version-10.0.0-beta04 to feat/split-auth-state-aborted August 6, 2026 11:57
@demolaf

demolaf commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

Waiting on this PR #2440 after which we can merge this.

@demolaf
demolaf force-pushed the fix/2422-google-signin-cancel branch from 0c191b4 to e3deeb8 Compare August 7, 2026 09:08
@demolaf
demolaf changed the base branch from feat/split-auth-state-aborted to version-10.0.0-beta04 August 7, 2026 09:09
@demolaf
demolaf requested a review from russellwheatley August 7, 2026 09:11
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.

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

2 participants