Skip to content

fix(auth): auto-register encoded app ID URL scheme for phone auth reCAPTCHA#8902

Open
ihor-sviziev wants to merge 3 commits intoinvertase:mainfrom
ihor-sviziev:fix/auth-expo-plugin-recaptcha-url-scheme
Open

fix(auth): auto-register encoded app ID URL scheme for phone auth reCAPTCHA#8902
ihor-sviziev wants to merge 3 commits intoinvertase:mainfrom
ihor-sviziev:fix/auth-expo-plugin-recaptcha-url-scheme

Conversation

@ihor-sviziev
Copy link

@ihor-sviziev ihor-sviziev commented Feb 25, 2026

Summary

The @react-native-firebase/auth Expo config plugin now derives the Encoded App ID from GOOGLE_APP_ID (always present in GoogleService-Info.plist) and registers it as a CFBundleURLScheme alongside REVERSED_CLIENT_ID.

Problem

Firebase phone auth reCAPTCHA fallback on iOS requires the Encoded App ID to be registered as a URL scheme. Since April 2023, REVERSED_CLIENT_ID is only present in GoogleService-Info.plist when Google Sign-In is enabled — so apps using only phone auth had a broken reCAPTCHA fallback (silently failing on Simulator and devices without APNs).

Changes

  • packages/auth/plugin/src/ios/urlTypes.ts

    • Added getEncodedAppId() which reads GOOGLE_APP_ID and transforms it to the Encoded App ID format:
      1:123456789012:ios:abc123app-1-123456789012-ios-abc123
    • setUrlTypesForCaptcha() now always registers the encoded app ID in addition to REVERSED_CLIENT_ID (when present)
    • Only one warning is shown — when REVERSED_CLIENT_ID is absent (Google Sign-In not enabled)
  • Tests / fixtures

    • New fixture: TestGoogleService-Info.no-reversed-client-id.plist — simulates a phone-auth-only app
    • Updated existing test for the empty-plist case to assert exactly one warning
    • New test + snapshot for the phone-auth-only case
    • Renamed the full-plist snapshot test to be more descriptive

Behaviour after fix

Situation URL schemes registered
Both REVERSED_CLIENT_ID + GOOGLE_APP_ID REVERSED_CLIENT_ID + Encoded App ID
Only GOOGLE_APP_ID (phone auth only, no Google Sign-In) Encoded App ID

…APTCHA

The auth Expo config plugin now derives the Encoded App ID from
GOOGLE_APP_ID (always present in GoogleService-Info.plist) and registers
it as a CFBundleURLScheme, in addition to REVERSED_CLIENT_ID.

This is required for Firebase phone auth reCAPTCHA fallback on iOS
(e.g. Simulator, any device without APNs) even when Google Sign-In is
not enabled. Since April 2023 REVERSED_CLIENT_ID is only present when
Google Sign-In is enabled, so apps using only phone auth had a broken
reCAPTCHA fallback.

Transformation: '1:123456789012:ios:abc123' -> 'app-1-123456789012-ios-abc123'

Fixes invertase#8901
…T_ID

Remove the separate GOOGLE_APP_ID warning - it is always present in any
valid GoogleService-Info.plist so showing a second warning is noise.
The encoded app ID is now added silently via try/catch; a malformed plist
is already surfaced by the earlier file-existence and parse checks.
Copilot AI review requested due to automatic review settings February 25, 2026 11:25
@vercel
Copy link

vercel bot commented Feb 25, 2026

@ihor-sviziev is attempting to deploy a commit to the Invertase Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant
Copy link

CLAassistant commented Feb 25, 2026

CLA assistant check
All committers have signed the CLA.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes an issue where Firebase phone authentication's reCAPTCHA fallback on iOS was silently failing for apps that don't have Google Sign-In enabled. The fix auto-generates and registers the Encoded App ID URL scheme from GOOGLE_APP_ID (which is always present in GoogleService-Info.plist), making phone auth reCAPTCHA work correctly on iOS Simulator and devices without APNs.

Changes:

  • Added getEncodedAppId() function to derive the Encoded App ID from GOOGLE_APP_ID by transforming format from 1:123456789012:ios:abc123 to app-1-123456789012-ios-abc123
  • Updated setUrlTypesForCaptcha() to always register the encoded app ID URL scheme in addition to REVERSED_CLIENT_ID (when present)
  • Added comprehensive test coverage with new fixture file and test cases to verify behavior with and without REVERSED_CLIENT_ID

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
packages/auth/plugin/src/ios/urlTypes.ts Added getEncodedAppId() function and updated setUrlTypesForCaptcha() to register encoded app ID URL scheme
packages/auth/plugin/tests/iosPlugin_urlTypes.test.ts Added test for phone-auth-only scenario and updated existing test to verify warning count
packages/auth/plugin/tests/fixtures/TestGoogleService-Info.no-reversed-client-id.plist New fixture simulating a phone-auth-only app (has GOOGLE_APP_ID but no REVERSED_CLIENT_ID)
packages/auth/plugin/tests/snapshots/iosPlugin_urlTypes.test.ts.snap Updated snapshots to reflect new URL schemes being registered
Comments suppressed due to low confidence (2)

packages/auth/plugin/src/ios/urlTypes.ts:54

  • The function should validate that GOOGLE_APP_ID exists and is a non-empty string before calling .replace() on it. If GOOGLE_APP_ID is undefined or not a string, the code will throw a TypeError when attempting to call .replace(), and this error will be caught by the outer catch block, leading to a misleading error message that mentions parsing failure rather than a missing field.

Consider adding validation after line 53:

if (!GOOGLE_APP_ID || typeof GOOGLE_APP_ID !== 'string') {
  throw new Error(
    '[@react-native-firebase/auth] Failed to parse your GoogleService-Info.plist. Are you sure it is a valid Info.Plist file with a GOOGLE_APP_ID field?',
  );
}

This ensures the error message accurately reflects the actual problem.

    const GOOGLE_APP_ID = googleServiceJson.GOOGLE_APP_ID;
    return 'app-' + GOOGLE_APP_ID.replace(/:/g, '-');

packages/auth/plugin/src/ios/urlTypes.ts:130

  • The comment mentions "file-existence and parse checks" but there are no parse checks performed before this point in the function. The only validation is the file existence check on line 105. This comment should be updated to accurately reflect what checks are actually performed, for example: "silently skip — a missing GOOGLE_APP_ID means the plist is malformed or invalid; the user will encounter other Firebase configuration errors"
    // silently skip — a missing GOOGLE_APP_ID means the plist is malformed;
    // the file-existence and parse checks above will have already surfaced the real problem.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Fix typo: 'GoogleServices-Info.plist' -> 'GoogleService-Info.plist'
- Fix grammar: 'requires this is' -> remove redundant word
- Clarify scope: warning now states only Google Sign-In is affected
- Add note that phone auth reCAPTCHA still works via the Encoded App ID
Copy link
Collaborator

@mikehardy mikehardy left a comment

Choose a reason for hiding this comment

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

Nice! This looks good and fixes a real problem for folks, much appreciated

@ihor-sviziev
Copy link
Author

ihor-sviziev commented Mar 6, 2026

@mikehardy I see tests are passing. Is there anything left?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[auth][iOS][Expo] Expo config plugin should auto-generate CFBundleURLSchemes for phone auth reCAPTCHA from GOOGLE_APP_ID

4 participants