Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(auth, iOS): Expo plugin: skip expo-router for auth URLs #8203

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

jey
Copy link

@jey jey commented Dec 26, 2024

Description

Summary:
Fix #7258: @react-native-firebase/auth (phone auth) + Expo Router - Redirected to appScheme://firebaseuth/link after resolving recaptcha in ios simulator

Problem:
When using @react-native-firebase/auth and expo-router in the same application, the phone number login method on iOS fails in some scenarios. In particular, when Firebase uses its ReCAPTCHA verifier (e.g. when running in the iOS simulator), the application ends up navigating away from the login page to a new route /firebaseauth/link.

Cause:
After the user has completed the captcha challenge, the WebView redirects back to the application using an iOS deep link of the form ${googleServiceJson.REVERSED_CLIENT_ID}://firebaseauth/link?${queryParams}. This inadvertently gets handled by Expo Router, which treats it as a navigation event to a route called /firebaseauth/link.

The root cause of this is a bad interaction between a feature in the Firebase iOS SDK and one in Expo Router:

  • Firebase uses a technique called "swizzling" to automatically intercept the openURL call and do its business, but then it also passes along the same openURL call to our application so we can handle it too.
  • Our iOS app's AppDelegate is supposed to return TRUE if it can handle the provided URL, and FALSE if it can't.
  • When using Expo Router, our AppDelegate is configured to just pass the URL along onto the router.
  • However, Expo Router always answers "yes I can handle this URL" -- even if it's going to "handle" it by displaying a "Not Found" error.

This interacts badly because it's effectively like Expo Router is hijacking the call that's intended for Firebase Auth. Yet, this situation only occurs because Firebase Auth is forwarding the openURL call to our app even after it has already handled it.

Solution:
This PR automatically updates the AppDelegate's openURL method to not handle URLs for the hostname "firebaseauth", under the assumption that it's already being handled by Firebase.

  • Adds a configuration option to @react-native-firebase/auth Expo plugin called captchaOpenUrlFix.
  • When captchaOpenUrlFix option is unset or "default", automatically applies patch if expo-router plugin is detected in Expo config.
  • Robust error handling and reporting

TODO:

  • Documentation updates

CC: @mikehardy

Related issues

Fixes #7258, #7953

Release Summary

Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
    • Yes
  • My change supports the following platforms;
    • Android
    • iOS
  • My change includes tests;
    • e2e tests added or updated in packages/\*\*/e2e
    • jest tests added or updated in packages/\*\*/__tests__
  • I have updated TypeScript types that are affected by my change.
  • This is a breaking change;
    • Yes
    • No

Test Plan

Comprehensive unit tests have been added:

  • plugin configurations
  • positive and negative examples of patching
  • tests for each error handling condition

Copy link

vercel bot commented Dec 26, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
react-native-firebase ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 28, 2024 11:58am

@CLAassistant
Copy link

CLAassistant commented Dec 26, 2024

CLA assistant check
All committers have signed the CLA.

@jey jey changed the title DRAFT: fix(auth, iOS): Expo plugin: don't invoke expo-router for openURL DRAFT: fix(auth, iOS): Expo plugin: don't invoke expo-router for auth URLs Dec 26, 2024
@jey jey changed the title DRAFT: fix(auth, iOS): Expo plugin: don't invoke expo-router for auth URLs DRAFT: fix(auth, iOS): Expo plugin: skip expo-router for auth URLs Dec 26, 2024
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.

Oh wow - you are quick with this one!

As mentioned in the related issue, it's a bit delicate because it has to do regex-matching so it will likely break across some future version, but also, I'm not aware of any other way to do this

Given the fragility I think it has to be default-off and have a parameter that turns on this logic (named anything reasonable, like maybe "expoRouterCompatibilityPatch" ... or something)

If it had that, then most people could use the plugin perfectly safely and never break, and those that needed this would be the only ones affected

But in general: thanks so much for posting up a PR to help folks, we rely on community submissions for Expo stuff so it's a huge help here

@jey jey marked this pull request as draft December 28, 2024 05:50
@jey jey changed the title DRAFT: fix(auth, iOS): Expo plugin: skip expo-router for auth URLs fix(auth, iOS): Expo plugin: skip expo-router for auth URLs Dec 28, 2024
@jey
Copy link
Author

jey commented Dec 28, 2024

@mikehardy This is now ready for review, but I'm also hoping to push some documentation updates later, within the next few days.

I made the plugin configurable as you suggested, but I also made it so that in the default configuration, it will automatically apply the patch only if "expo-router" is also detected (by looking in the Expo Plugins list). I think this is a happy medium because it addresses the edge cases of projects where it's not applicable, but also makes it easy for the median Expo user. My impression is that the typical Expo user is not comfortable dealing with native code and having even more manual configuration changes to apply and figure out on top of the already complex configuration required for RNFirebase Phone Auth to work.

@jey
Copy link
Author

jey commented Dec 30, 2024

CC: @Brandon-Perry

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants