fix(auth): auto-register encoded app ID URL scheme for phone auth reCAPTCHA#8902
fix(auth): auto-register encoded app ID URL scheme for phone auth reCAPTCHA#8902ihor-sviziev wants to merge 3 commits intoinvertase:mainfrom
Conversation
…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.
|
@ihor-sviziev is attempting to deploy a commit to the Invertase Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
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 fromGOOGLE_APP_IDby transforming format from1:123456789012:ios:abc123toapp-1-123456789012-ios-abc123 - Updated
setUrlTypesForCaptcha()to always register the encoded app ID URL scheme in addition toREVERSED_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_IDexists and is a non-empty string before calling.replace()on it. IfGOOGLE_APP_IDis 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
mikehardy
left a comment
There was a problem hiding this comment.
Nice! This looks good and fixes a real problem for folks, much appreciated
|
@mikehardy I see tests are passing. Is there anything left? |
Summary
The
@react-native-firebase/authExpo config plugin now derives the Encoded App ID fromGOOGLE_APP_ID(always present inGoogleService-Info.plist) and registers it as aCFBundleURLSchemealongsideREVERSED_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_IDis only present inGoogleService-Info.plistwhen 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.tsgetEncodedAppId()which readsGOOGLE_APP_IDand transforms it to the Encoded App ID format:1:123456789012:ios:abc123→app-1-123456789012-ios-abc123setUrlTypesForCaptcha()now always registers the encoded app ID in addition toREVERSED_CLIENT_ID(when present)REVERSED_CLIENT_IDis absent (Google Sign-In not enabled)Tests / fixtures
TestGoogleService-Info.no-reversed-client-id.plist— simulates a phone-auth-only appBehaviour after fix
REVERSED_CLIENT_ID+GOOGLE_APP_IDREVERSED_CLIENT_ID+ Encoded App IDGOOGLE_APP_ID(phone auth only, no Google Sign-In)