Skip to content

fix(auth,web): return signInSecondFactor from getIdTokenResult - #18895

Open
BiAksoy wants to merge 2 commits into
firebase:mainfrom
BiAksoy:fix/auth-web-sign-in-second-factor
Open

BiAksoy wants to merge 2 commits into
firebase:mainfrom
BiAksoy:fix/auth-web-sign-in-second-factor

Conversation

@BiAksoy

@BiAksoy BiAksoy commented Nov 3, 2026

Copy link
Copy Markdown

Description

On web, IdTokenResult.signInSecondFactor is always null, even after a multi-factor sign-in (for example email and password plus a TOTP code through MultiFactorResolver.resolveSignIn). The value is present in the token: claims['firebase']['sign_in_second_factor'] is 'totp'. Android and iOS already return it (PigeonParser.kt, PigeonParser.swift).

#17589 added signInSecondFactor to the platform interface, but firebase_auth_web never reads it:

This PR declares the property as JSString?, adds the getter and passes the value through. In the JS SDK the property is typed signInSecondFactor: string | null and is set to null when the token has no second factor (@firebase/auth 1.13.8, the version firebase 13.1.0 depends on, which firebase_core_web targets). A session without a second factor therefore still returns null, as on Android and iOS.

The new browser test feeds a JS object shaped like the SDK's IdTokenResult through User.getIdTokenResult and convertWebIdTokenResult, and checks both a 'totp' value and null. On main the first case fails with Expected: 'totp' Actual: <null>.

Run locally in packages/firebase_auth/firebase_auth_web: flutter test --platform=chrome and flutter test --platform=chrome --wasm (all 24 tests pass), dart analyze . --fatal-infos and dart format. I did not run it against a real multi-factor sign-in; the multi-factor e2e tests in the example app are skipped on web.

Related Issues

Follow-up to #17589, which added signInSecondFactor to the platform interface without the web implementation. There is no separate issue for this.

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]).
This will ensure a smooth and quick review process. Updating the pubspec.yaml and changelogs is not required.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • My PR includes unit or integration tests for all changed/updated/fixed behaviors (See Contributor Guide).
  • All existing and new tests are passing.
  • I updated/added relevant documentation (doc comments with ///).
  • The analyzer (melos run analyze) does not report any problems on my PR.
  • I read and followed the Flutter Style Guide.
  • I signed the CLA.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require plugin users to manually update their apps to accommodate your change?

  • Yes, this is a breaking change.
  • No, this is not a breaking change.

The JS SDK's IdTokenResult has signInSecondFactor, but the interop type
did not declare it, so the web implementation always returned null.

@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 support for the signInSecondFactor property in IdTokenResult for the Firebase Auth Web package, mapping it from the underlying JS object and adding unit tests to verify its behavior. The review feedback points out a violation of the repository's style guide regarding null safety, specifically the use of the non-null assertion operator (!) in the new test file, and suggests using flow analysis instead.

Comment on lines +38 to +41
final user = auth_interop.User.getInstance(
jsUser as auth_js_interop.UserJsImpl,
)!;
return user.getIdTokenResult(false);

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.

low

The repository style guide prohibits the use of the ! operator. Please use flow analysis or a null check instead.

    final user = auth_interop.User.getInstance(
      jsUser as auth_js_interop.UserJsImpl,
    );
    if (user == null) {
      throw StateError('User instance should not be null');
    }
    return user.getIdTokenResult(false);
References
  1. Null Safety: NO ! operator. Use ? and flow analysis (e.g. if (x != null)). (link)

This branch has not been deployed

No deployments
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.

1 participant