invertase / react-native-firebase

🔥 A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
https://rnfirebase.io
Other
11.71k stars 2.22k forks source link

[🐛🔥] @react-native-firebase/auth (phone auth) - Redirected to appScheme://firebaseuth/link after resolving recaptcha in ios simulator #7258

Closed bryanltobing closed 2 weeks ago

bryanltobing commented 1 year ago

Issue

Describe your issue here

I'm currently developing a phone authentication for my ios app using @react-native-firebase/auth specifically Phone Auth

in ios simulator we don't have access to Silent APNs notifications for app verification and we will need to resolve recaptcha instead ref: image

The integration went smoothly, but when I tried to resolve the reCAPTCHA on the simulator, I got redirected to appScheme://firebaseuth/link. I believe it's a deep link to that route.

Since I use expo-router, it automatically detects that link and redirected to that screen as shown in this video

https://github.com/invertase/react-native-firebase/assets/46083126/d974cb90-2dce-4d0a-b97e-c6e0f06ae46c

Expected Result

It should stay with the current screen after resolving the captcha


Project Files

Javascript

Click To Expand

#### `package.json`: ```json { "name": "", "version": "1.0.0", "main": "expo-router/entry", "scripts": { "start": "expo start", "android": "expo run:android", "ios": "expo run:ios", "web": "expo start --web", "lint": "echo \"Running eslint check\" && eslint --fix .", "tsc": "tsc" }, "dependencies": { "@react-native-firebase/app": "^18.3.0", "@react-native-firebase/auth": "^18.3.0", "expo": "~49.0.3", "expo-build-properties": "~0.8.3", "expo-constants": "~14.4.2", "expo-dev-client": "~2.4.6", "expo-linking": "~5.0.2", "expo-router": "2.0.0", "expo-splash-screen": "~0.20.4", "expo-status-bar": "~1.6.0", "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.72.3", "react-native-gesture-handler": "~2.12.0", "react-native-safe-area-context": "4.6.3", "react-native-screens": "~3.22.0", "react-native-web": "~0.19.6" }, "devDependencies": { "@babel/core": "^7.20.0", "@types/react": "~18.2.14", "eslint": "^8.45.0", "eslint-config-universe": "^11.3.0", "eslint-plugin-prettier": "5.0.0", "eslint-plugin-react-hooks": "^4.6.0", "prettier": "^3.0.0", "typescript": "^5.1.3" }, "private": true } ``` #### `firebase.json` for react-native-firebase v6: ```json # N/A ```

iOS

Click To Expand

#### `ios/Podfile`: - [x] I'm not using Pods - [] I'm using Pods and my Podfile looks like: ```ruby # N/A ``` #### `AppDelegate.m`: ```objc // N/A ```


Android

Click To Expand

#### Have you converted to AndroidX? - [ ] my application is an AndroidX application? - [ ] I am using `android/gradle.settings` `jetifier=true` for Android compatibility? - [ ] I am using the NPM package `jetifier` for react-native compatibility? #### `android/build.gradle`: ```groovy // N/A ``` #### `android/app/build.gradle`: ```groovy // N/A ``` #### `android/settings.gradle`: ```groovy // N/A ``` #### `MainApplication.java`: ```java // N/A ``` #### `AndroidManifest.xml`: ```xml ```


Environment

Click To Expand

**`react-native info` output:** ``` OS: macOS 13.4.1 CPU: (8) arm64 Apple M1 Memory: 103.33 MB / 8.00 GB Shell: version: "5.9" path: /bin/zsh Binaries: Node: version: 20.3.1 path: /opt/homebrew/bin/node Yarn: version: 1.22.19 path: /opt/homebrew/bin/yarn npm: version: 9.6.7 path: /opt/homebrew/bin/npm Watchman: version: 2023.06.26.00 path: /opt/homebrew/bin/watchman Managers: CocoaPods: version: 1.12.1 path: /Users/bryan/.gem/ruby/2.7.6/bin/pod SDKs: iOS SDK: Platforms: - DriverKit 22.4 - iOS 16.4 - macOS 13.3 - tvOS 16.4 - watchOS 9.4 Android SDK: API Levels: - "29" - "31" - "32" - "33" - "34" Build Tools: - 30.0.2 - 30.0.3 - 31.0.0 - 33.0.0 - 34.0.0 System Images: - android-33 | Google APIs ARM 64 v8a - android-34 | Google APIs ARM 64 v8a Android NDK: Not Found IDEs: Android Studio: 2022.2 AI-222.4459.24.2221.10121639 Xcode: version: 14.3.1/14E300c path: /usr/bin/xcodebuild Languages: Java: version: 11.0.19 path: /usr/bin/javac Ruby: version: 2.7.6 path: /Users/bryan/.rubies/ruby-2.7.6/bin/ruby npmPackages: "@react-native-community/cli": Not Found react: installed: 18.2.0 wanted: 18.2.0 react-native: installed: 0.72.3 wanted: 0.72.3 react-native-macos: Not Found npmGlobalPackages: "*react-native*": Not Found Android: hermesEnabled: true newArchEnabled: false iOS: hermesEnabled: true newArchEnabled: false ``` - **Platform that you're experiencing the issue on**: - [x] iOS - [ ] Android - [ ] **iOS** but have not tested behavior on Android - [ ] **Android** but have not tested behavior on iOS - [ ] Both - **`react-native-firebase` version you're using that has this issue:** - "@react-native-firebase/app": "^18.3.0", "@react-native-firebase/auth": "^18.3.0", - **`Firebase` module(s) you're using that has the issue:** - firebase phone auth - **Are you using `TypeScript`?** - Yes


noickare commented 1 year ago

Try expo-router unmatched route as described https://docs.expo.dev/routing/error-handling/ and check the path name and if it matches firebaseauthlink redirect back see code sample below.

function UnmatchedScreen(props: UnmatchedProps) {
    const param = useGlobalSearchParams();

    if (param.unmatched === 'firebaseauth,link') {
        return <Redirect href="../" />;
    }

    return (
        <View>
            <Text>404</Text>
       </View>
    );
}
chen-rn commented 1 year ago

Running into the same issue!

Anyone know why it's redirecting to a deep link? Is it possible to change it?

lsps9150414 commented 1 year ago

Same, can't find any document to customize this behavior

github-actions[bot] commented 1 year ago

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

lsps9150414 commented 1 year ago

Still waiting for reply 🙏🏻

riccardogiorato commented 1 year ago

Having this exact same issue, don't close the issue

balgamat commented 1 year ago

Same here.

github-actions[bot] commented 11 months ago

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

lsps9150414 commented 11 months ago

Still waiting for reply

Kledal commented 11 months ago

I'm running into the same issue. Seems to originate from the recaptcha triggered by firebase authentication that tries to redirect to app-schema://firebaseauth/link, which the expo-router catches

mikehardy commented 11 months ago

This is an open source repository, all updates are visible in the form of comments here. The only updates are people asking for updates, no one appears to have the time to investigate and provide more information. If this is impacting you, allocating resources to troubleshoot it in depth is the way to move it forward

github-actions[bot] commented 10 months ago

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

micaeldias commented 9 months ago

For Expo v50 with expo-router I had to use the following:

import { Unmatched, Redirect, useGlobalSearchParams } from "expo-router";

export default () => {
    const param = useGlobalSearchParams<{ unmatched: string[] }>();

    if (isFirebaseCallback(param.unmatched)) {
        return <Redirect href="/auth/sign-in" />;
    }

    return <Unmatched />;
};

const isFirebaseCallback = (unmatched: string[] | undefined) => {
    return (
        unmatched?.length === 2 &&
        unmatched[0] === "firebaseauth" &&
        unmatched[1] === "link"
    );
};
joaqo commented 9 months ago

I have the same issue.

iarmankhan commented 9 months ago

Can we please reopen this issue? I was able to use @micaeldias 's code, but it doesn't keep the state of that screen. How can we keep the local state?

mikehardy commented 9 months ago

Sure, can reopen. Please note this is an open source repository. If this is important to you, devoting resources to finding the root cause and proposing a PR is the way to get it fixed

2n2n commented 8 months ago

for those who have the same problem you just need to create a route for /firebaseauth/link.js that route should be found. that's where we put the OTP screen afterwards

github-actions[bot] commented 7 months ago

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

iarmankhan commented 7 months ago

Hey @2n2n How do you maintain the state of your app? The confirmation is in state and it got lost

github-actions[bot] commented 6 months ago

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

vinhandev commented 6 months ago

Hey @2n2n How do you maintain the state of your app? The confirmation is in state and it got lost

you can use a state management like redux or zustand for confirmation.

2n2n commented 6 months ago

Hey @2n2n How do you maintain the state of your app? The confirmation is in state and it got lost

Hi @iarmankhan, I just rely on the response of my auth auth().onAuthStateChanged(onAuthStateChanged) and store the data using react context. I just let Firebase handle my session.

al3xstathis commented 6 months ago

@2n2n can you elaborate more? When calling the sign in with phone number it returns a function to then use the sms code. How do you use that function when state is lost from going to the new page?

adnaneghalem commented 6 months ago

@vinhandev what do you mean ?

adnaneghalem commented 6 months ago

@bryanltobing I have the exact same issue, and I am not finding a workaround. Any idea since ? :)

github-actions[bot] commented 5 months ago

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

abdu-zeyad commented 4 months ago

Same here

ryan-setifly commented 4 months ago

@al3xstathis while I could not replicate @2n2n's Solution, I found another that seemed to solve the problem for me. Instead of handling the OTP on /firebaseauth/link.js I just redirect backwards from that page and keep my otp on the login screen like such:

import { router } from "expo-router";
import React, { useEffect } from "react";
import { View } from "react-native";

export default function FirebaseauthLinkPage() {

  useEffect(() => {
    router.back();
  }, []);

  return (
    <View>
    </View>
  );
}
aniketkhetan commented 4 months ago

@al3xstathis while I could not replicate @2n2n's Solution, I found another that seemed to solve the problem for me. Instead of handling the OTP on /firebaseauth/link.js I just redirect backwards from that page and keep my otp on the login screen like such:

import { router } from "expo-router";
import React, { useEffect } from "react";
import { View } from "react-native";

export default function FirebaseauthLinkPage() {

  useEffect(() => {
    router.back();
  }, []);

  return (
    <View>
    </View>
  );
}

For me when I return to the login screen of my app the state is still lost has anyone found a solution that works since?

Misterr-H commented 3 months ago

@al3xstathis while I could not replicate @2n2n's Solution, I found another that seemed to solve the problem for me. Instead of handling the OTP on /firebaseauth/link.js I just redirect backwards from that page and keep my otp on the login screen like such:

import { router } from "expo-router";
import React, { useEffect } from "react";
import { View } from "react-native";

export default function FirebaseauthLinkPage() {

  useEffect(() => {
    router.back();
  }, []);

  return (
    <View>
    </View>
  );
}

This solution worked for me. Thankyou very much

Misterr-H commented 3 months ago

@al3xstathis while I could not replicate @2n2n's Solution, I found another that seemed to solve the problem for me. Instead of handling the OTP on /firebaseauth/link.js I just redirect backwards from that page and keep my otp on the login screen like such:

import { router } from "expo-router";
import React, { useEffect } from "react";
import { View } from "react-native";

export default function FirebaseauthLinkPage() {

  useEffect(() => {
    router.back();
  }, []);

  return (
    <View>
    </View>
  );
}

For me when I return to the login screen of my app the state is still lost has anyone found a solution that works since?

State must not be lost since screen is still exiting in route stack

github-actions[bot] commented 3 months ago

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

russellwheatley commented 3 months ago

This isn't a bug, it's a way for Firebase Auth to send the user back to the app post recaptcha completion. You can customise the URL if you prefer it to have a different value:

It's something like this:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>com.yourapp.app</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>yourcustomscheme</string>
        </array>
    </dict>
</array>

either way, you'll have to handle the URL in your expo navigation once the deeplink redirects to your app after recaptcha. There is nothing to fix from RNFB side. There are a number of suggestions already in this thread that covers ways to handle this. Labelling as a documentation issue.

dicompathakofficial commented 2 months ago

SOLUTION FOUND !! AT [https://docs.expo.dev/router/error-handling/] just create a new file called +not-found.tsx at inside app. app/+not-found.tsx and inside it only have import { Unmatched } from "expo-router"; export default Unmatched; So by default no 404 pages will be shown. Do lemme know if it helps. Cheers

emrahaydemir commented 2 months ago

It's frustrating not being able to set the redirect route after solving the captcha. I didn't expect that I might have to redirect it through a hack. I've been working on this issue for a few hours now. To be honest, I thought this would be easily resolved.

emrahaydemir commented 2 months ago

For now, I'll implement a similar solution. Here's what I did:

I made a small change to my not-found page so that it redirects back directly without actually accessing the missing page.


import { View, Text } from "react-native";
import React, { useEffect } from "react";
import { usePathname, useRouter } from "expo-router";

export default function NotFound() {
  const pathname = usePathname();
  const router = useRouter();
  useEffect(() => {
    if (pathname == "/firebaseauth/link") router.back();
  }, [pathname]);

  return (
    <View>
      <Text>not_found</Text>
    </View>
  );
}
andepants commented 2 months ago

For now, I'll implement a similar solution. Here's what I did:

I made a small change to my not-found page so that it redirects back directly without actually accessing the missing page.

import { View, Text } from "react-native";
import React, { useEffect } from "react";
import { usePathname, useRouter } from "expo-router";

export default function NotFound() {
  const pathname = usePathname();
  const router = useRouter();
  useEffect(() => {
    if (pathname == "/firebaseauth/link") router.back();
  }, [pathname]);

  return (
    <View>
      <Text>not_found</Text>
    </View>
  );
}

Worked like a charm thank you!

github-actions[bot] commented 1 month ago

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.