Skip to content

feat(auth): onUpgradeFailure callback when account linking fails#1355

Open
russellwheatley wants to merge 11 commits into
mainfrom
issue-1354-auto-upgrade-anon-user
Open

feat(auth): onUpgradeFailure callback when account linking fails#1355
russellwheatley wants to merge 11 commits into
mainfrom
issue-1354-auto-upgrade-anon-user

Conversation

@russellwheatley

@russellwheatley russellwheatley commented May 6, 2026

Copy link
Copy Markdown
Member
  • Adds an onUpgradeFailure callback for anonymous user auto-upgrade failures.
  • Allows apps to handle account-linking conflicts and suppress the default FirebaseUI error by returning "handled".
  • Preserves anonymous user upgrade state correctly across provider redirect flows.
  • Extends onUpgradeFailure to redirect-completed linking failures (e.g. auth/email-already-in-use from getRedirectResult()), which previously bypassed the callback and always showed the default error.
  • Adds unit tests for credential, provider, failure-handling, and redirect upgrade behavior, including the new redirect-failure paths.
  • Adds Playwright e2e coverage (react + angular) for credential/provider upgrades, conflict callbacks, handled errors, and redirect-based linking conflicts (shown and suppressed).

closes #1354

Below demonstrates onUpgradeFailure firing when auto upgrade anonymous user fails and also returns "handled" so error message does not appear in the UI.

Screen.Recording.2026-05-07.at.16.47.44.mov

@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 introduces an onUpgradeFailure callback to the anonymous upgrade behaviors, allowing for custom error handling and suppression during the linking process. The changes include new type definitions, a centralized error handling utility, and updated logic for both credential and provider linking handlers. A critical issue was identified in the provider linking implementation where the unconditional removal of the user ID from local storage in a finally block would disrupt the redirect flow.

Comment thread packages/core/src/behaviors/anonymous-upgrade.ts Outdated
@russellwheatley
russellwheatley requested a review from dackers86 May 6, 2026 14:55
@russellwheatley
russellwheatley marked this pull request as ready for review May 6, 2026 14:55
@russellwheatley

Copy link
Copy Markdown
Member Author

I think I'd like to get some integration tests setup for this before going further with this PR as there are some changes to core behaviour.

@github-actions

This comment was marked as outdated.

@github-actions github-actions Bot added the stale label Jun 12, 2026
@mikehardy

Copy link
Copy Markdown
Contributor

plan here:

  • bring up an initial playwright testing implementation for e2e
  • set this area / flow up as the initial test for a baseline to show the problem
  • verify this fixes the issue
  • merge

@mikehardy mikehardy removed the stale label Jun 22, 2026
Verify existing anonymous user auto-upgrade behavior is unchanged.

Verify the new onUpgradeFailure callback fires correctly on account-linking conflicts.

Verify returning "handled" from the callback suppresses the default FirebaseUI error UI.

Verify anonymous user upgrade state is preserved correctly across provider redirect flows.
Global setup dropped the execSync import while removing the unused
runBuildPackages() helper, but ensureFirebaseToolsCached() still calls
execSync. The resulting ReferenceError was swallowed by a bare catch
and rethrown as a misleading "Auth emulator cannot start" error,
failing the ui-e2e CI job before any tests could run.
…ures

getRedirectResult() rejections (e.g. auth/email-already-in-use when
linking a provider via providerRedirectStrategy) previously bypassed
onUpgradeFailure entirely and always fell through to the default
FirebaseUI error, so redirect-based conflicts couldn't be customized
or suppressed like popup/credential ones.

Give redirect behaviors a chance to handle the getRedirectResult()
error in config.ts before the default handler runs, and wire
autoUpgradeAnonymousUserRedirectHandler to invoke onUpgradeFailure
(with oldUserId and a best-effort recovered credential) and signal
"handled" back up when the callback suppresses the error.

Add unit coverage for the new redirect-failure paths and e2e coverage
(react + angular) for a redirect-based linking conflict, both shown
and suppressed.

@mikehardy mikehardy 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.

LGTM - I had a personal curiosity if these test files - which are living next to the implementation files were leaking into releases in any way - verified they are not. Code all fine and all the testing is excellent. Really happy to see the e2e stuff working out

@russellwheatley
russellwheatley requested a review from jhuleatt July 15, 2026 16:16
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.

autoUpgradeAnonymousUsers onUpgrade event not invoked if merge is required.

2 participants