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

[🐛] Cannot use auth emulator on real iOS device - only on iOS simulator #8060

Open
7 tasks
SKempin opened this issue Oct 14, 2024 · 12 comments
Open
7 tasks
Labels

Comments

@SKempin
Copy link

SKempin commented Oct 14, 2024

Issue

When attempting to run the auth emulator I cannot sign in on a real iOS device. Using iOS simulator works fine. I am using signInWithEmailAndPassword.

When running my Expo dev build on device and attempting to sign in I am continually met with the following:

ERROR Error: [auth/network-request-failed] A network error has occurred, please try again.

I have tried setting the host address in firebase.json and using my host device IP as discussed but this still results in the same behaviour.
#4934 (comment)

  firestore().useEmulator('127.0.0.1', 8080);
  auth().useEmulator('http://192.168.86.1:9099'); // using host machine IP still does not fix the issue on a real iOS device
  console.log('Firestore emulators running!');
  analytics().setAnalyticsCollectionEnabled(false);
{
  "emulators": {
    "auth": {
      "port": 9099,
      "host": "0.0.0.0"
    },
    "firestore": {
      "port": 8080,
      "host": "0.0.0.0"
    },
    "ui": {
      "enabled": true
    },
    "singleProjectMode": true
  }
}


Project Files

Javascript

Click To Expand

package.json:

{
  "name": "demo-app",
  "version": "1.0.0",
  "scripts": {
    "start": "expo start --dev-client",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "expo start --web",
    "test": "jest --watchAll"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@amplitude/analytics-react-native": "^1.4.10",
    "@eva-design/eva": "^2.2.0",
    "@expo/vector-icons": "^14.0.0",
    "@hookform/resolvers": "^3.3.4",
    "@logrocket/react-native": "^1.41.1",
    "@react-native-async-storage/async-storage": "1.23.1",
    "@react-native-community/slider": "4.5.2",
    "@react-native-firebase/analytics": "^21.0.0",
    "@react-native-firebase/app": "^21.0.0",
    "@react-native-firebase/auth": "^21.0.0",
    "@react-native-firebase/crashlytics": "^21.0.0",
    "@react-native-firebase/firestore": "^21.0.0",
    "@react-navigation/native": "^6.0.2",
    "@sentry/react-native": "~5.22.0",
    "@ui-kitten/components": "^5.3.1",
    "date-fns": "^2.30.0",
    "expo": "^51.0.0",
    "expo-application": "~5.9.1",
    "expo-build-properties": "~0.12.3",
    "expo-constants": "~16.0.2",
    "expo-dev-client": "~4.0.19",
    "expo-device": "~6.0.2",
    "expo-font": "~12.0.7",
    "expo-haptics": "~13.0.1",
    "expo-image": "~1.12.12",
    "expo-linear-gradient": "~13.0.2",
    "expo-linking": "~6.3.1",
    "expo-location": "~17.0.1",
    "expo-network": "~6.0.1",
    "expo-notifications": "~0.28.17",
    "expo-router": "3.4.6",
    "expo-screen-capture": "^6.0.1",
    "expo-splash-screen": "~0.27.5",
    "expo-status-bar": "~1.12.1",
    "expo-system-ui": "~3.0.7",
    "expo-web-browser": "~13.0.3",
    "geofire-common": "^6.0.0",
    "numeral": "^2.0.6",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-error-boundary": "^4.0.13",
    "react-hook-form": "^7.50.0",
    "react-native": "0.74.3",
    "react-native-gesture-handler": "~2.16.1",
    "react-native-maps": "1.14.0",
    "react-native-safe-area-context": "4.10.1",
    "react-native-screens": "3.31.1",
    "react-native-shimmer-placeholder": "^2.0.9",
    "react-native-svg": "15.2.0",
    "react-native-web": "~0.19.6",
    "vexo-analytics": "^1.3.15",
    "yup": "^1.3.3"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@types/numeral": "^2.0.5",
    "@types/react": "~18.2.45",
    "jest": "^29.2.1",
    "jest-expo": "~51.0.3",
    "react-test-renderer": "18.2.0",
    "typescript": "~5.3.3"
  },
  "private": true
}

firebase.json for react-native-firebase v6:

{
  "emulators": {
    "auth": {
      "port": 9099,
      "host": "0.0.0.0"
    },
    "firestore": {
      "port": 8080,
      "host": "0.0.0.0"
    },
    "ui": {
      "enabled": true
    },
    "singleProjectMode": true
  }
}

iOS

Click To Expand

ios/Podfile:

  • [x ] I'm not using Pods
  • [] I'm using Pods and my Podfile looks like:
# N/A

AppDelegate.m:

// N/A


Android (Not able to be tested on 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:

// N/A

android/app/build.gradle:

// N/A

android/settings.gradle:

// N/A

MainApplication.java:

// N/A

AndroidManifest.xml:

<!-- N/A -->


Environment

Click To Expand

react-native info output:

  OS: macOS 14.6.1
  CPU: (12) arm64 Apple M2 Pro
  Memory: 93.52 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.17.0
    path: ~/.nvm/versions/node/v20.17.0/bin/node
  Yarn:
    version: 1.22.22
    path: /opt/homebrew/bin/yarn
  npm:
    version: 10.8.2
    path: ~/.nvm/versions/node/v20.17.0/bin/npm
  Watchman:
    version: 2024.07.15.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.0
      - iOS 18.0
      - macOS 15.0
      - tvOS 18.0
      - visionOS 2.0
      - watchOS 11.0
  Android SDK: Not Found
IDEs:
  Android Studio: 2023.3 AI-233.14808.21.2331.11709847
  Xcode:
    version: 16.0/16A242d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.11
    path: /usr/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.74.3
    wanted: 0.74.3
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: false

  • Platform that you're experiencing the issue on:
    • iOS
    • Android
    • [ x] 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:
    • 21
  • Firebase module(s) you're using that has the issue:
    • Auth
  • Are you using TypeScript?
    • Yes 5.3.3

@mikehardy
Copy link
Collaborator

Hmmm

When running my Expo dev build on device

How exactly was this build made?

Note this interesting case: #8049 (comment)

@SKempin
Copy link
Author

SKempin commented Oct 14, 2024

This was also built using EAS. It's a development build (I'm not using Expo go).

So it appears to be EAS related?

@mikehardy

@KieranTH
Copy link

KieranTH commented Oct 14, 2024

This was also built using EAS. It's a development build (I'm not using Expo go).

So it appears to be EAS related?

@mikehardy

Yeah, I'm not entirely sure why the EAS build fails vs a local prebuild. Could you try using the prebuild? It's a bit more of a pain to get those builds on device, you'd have to create the IPA/APK yourself and use Expo Orbit / XCode / Android Studio to sign it on device.

I haven't tried the emulator on a real device, only sims at the point.

Such a strange behaviour!

@mikehardy
Copy link
Collaborator

🤔 doesn't this seem like it's an Expo error? Like, this should not be happening, and there should be an issue in an Expo issue tracker, and they should fix this?

@SKempin
Copy link
Author

SKempin commented Oct 14, 2024

@KieranTH I've just done a development build using npx expo prebuild --clean and then pushing to EAS for the build itself. Same issue still persists.

Did you get it working this way? I have never done a local build, have always used EAS.

I've just tested an Android development build built on EAS and am experiencing the same issue.

@KieranTH
Copy link

KieranTH commented Oct 14, 2024

@KieranTH I've just done a development build using npx expo prebuild --clean and then pushing to EAS for the build itself. Same issue still persists.

Did you get it working this way? I have never done a local build, have always used EAS.

I've just tested an Android development build built on EAS and am experiencing the same issue.

Yeah, doing a local build solved it for me! (I didn't use EAS at all, just ran the local build on a sim)

That being said, I need to do some extra testing to make sure it's EAS and that EAS isn't a byproduct of another problem.

@mikehardy is right though, this doesn't feel like an issue for this project. I'll get time this weekend to do more robust testing and I'll make an issue on Expo if it persists

@SKempin
Copy link
Author

SKempin commented Oct 15, 2024

@KieranTH I did a local build for Android and got this running but still cannot sign in on device whilst using the auth emulator.

I used my IP from https://whatismyipaddress.com/ with the port 9099 - just double checking am I right in using this IP?

firestore().useEmulator('127.0.0.1', 8080);
auth().useEmulator('http://86.xx.xxx.xxx:9099'); // removed IP for example

@KieranTH
Copy link

@KieranTH I did a local build for Android and got this running but still cannot sign in on device whilst using the auth emulator.

I used my IP from https://whatismyipaddress.com/ with the port 9099 - just double checking am I right in using this IP?


firestore().useEmulator('127.0.0.1', 8080);

auth().useEmulator('http://86.xx.xxx.xxx:9099'); // removed IP for example

Have you made sure that your firebase.json has the host set as "0.0.0.0"?

Besides that I can't think of any other bits - That being said I don't test on a real device, only on sims, so i can't offer much help sadly!

@mikehardy
Copy link
Collaborator

mikehardy commented Oct 15, 2024

I used my IP from https://whatismyipaddress.com/ with the port 9099 - just double checking am I right in using this IP?

@SKempin That is most likely an "externally visible on the internet after your machine has gone through a NAT device" IP address, it is most likely not the IP address of your actual laptop on the internal network it shares with the iOS device

On a mac to get your actual IP address on your local network (not what it looks like to external servers on the public internet...) you want to click top right on menu bar on the control center icon then option-click on the wifi thing and you get an augmented wifi dropdown that has your IP address. On windows machines I think you want system preferences -> get into wifi somehow then probably advanced settings? I forget I just do it by muddling through but a search will turn it up for sure

Setting the listen IP to 0.0.0.0 for the emulators in firebase.json is also key - great point @KieranTH

It is also possible that your local router does not allow connections between devices even on the same network. I personally despite networks set up this way, but it is a configuration option in lots of routers and some routers have it enabled - specifically those that are in for example cafes or hotels where for security reasons I must admit it makes sense to disallow local devices from seeing each other

@SKempin
Copy link
Author

SKempin commented Oct 15, 2024

@mikehardy @KieranTH Thanks, have tried with the IP as per the Mac WIFI settings, and with the host as 0.0.0.0, but still getting an internal error.

This is on an Android device that has been built locally with npx expo prebuild --clean and npx expo run:android --device, and connected to my Mac via USB.

My router is Google Nest WiFi and I'm able to connect to devices remotely through this. The app is loading but logs the below error when I try to use auth().signInWithEmailAndPassword to sign in whilst using the emulator. Using the live project works fine.

For the time being I think I will need to create a "staging environment" in the Firebase console and develop any features that require a physical device using that.

ERROR Error: [auth/unknown] An internal error has occurred. [ Failed to connect to /192.168.86.24:9099 ]

  auth().useEmulator('http://192.168.86.24:9099');
{
  "emulators": {
    "auth": {
      "port": 9099,
      "host": "0.0.0.0"
    },
    "firestore": {
      "port": 8080,
      "host": "0.0.0.0"
    },
    "ui": {
      "enabled": true
    },
    "singleProjectMode": true
  }
}

@mikehardy
Copy link
Collaborator

Failed to connect to /192.168.86.24:9099

That slash looks really suspicious 🤔

If I were troubleshooting this I would:

1- make sure I can actually run a simple local connection manually to that IP:port combo, using curl or whatever
2- reach in and hack a console.error or something glaring I can see easily telling me what exact IP:port combo was being used right before the this.native call here:

useEmulator(url) {
if (!url || !isString(url) || !isValidUrl(url)) {
throw new Error('firebase.auth().useEmulator() takes a non-empty string URL');
}
let _url = url;
const androidBypassEmulatorUrlRemap =
typeof this.firebaseJson.android_bypass_emulator_url_remap === 'boolean' &&
this.firebaseJson.android_bypass_emulator_url_remap;
if (!androidBypassEmulatorUrlRemap && isAndroid && _url) {
if (_url.startsWith('http://localhost')) {
_url = _url.replace('http://localhost', 'http://10.0.2.2');
// eslint-disable-next-line no-console
console.log(
'Mapping auth host "localhost" to "10.0.2.2" for android emulators. Use real IP on real devices. You can bypass this behaviour with "android_bypass_emulator_url_remap" flag.',
);
}
if (_url.startsWith('http://127.0.0.1')) {
_url = _url.replace('http://127.0.0.1', 'http://10.0.2.2');
// eslint-disable-next-line no-console
console.log(
'Mapping auth host "127.0.0.1" to "10.0.2.2" for android emulators. Use real IP on real devices. You can bypass this behaviour with "android_bypass_emulator_url_remap" flag.',
);
}
}
// Native calls take the host and port split out
const hostPortRegex = /^http:\/\/([\w\d-.]+):(\d+)$/;
const urlMatches = _url.match(hostPortRegex);
if (!urlMatches) {
throw new Error('firebase.auth().useEmulator() unable to parse host and port from URL');
}
const host = urlMatches[1];
const port = parseInt(urlMatches[2], 10);
this.native.useEmulator(host, port);
return [host, port]; // undocumented return, useful for unit testing
}

3- maybe use adb port forwarding to forward the device port from the Android local IP address to the machine, so now a connection to localhost:9099 on the device will be forwarded (by adb) to your development machine, then use android_bypass_emulator_url_remap in the firebase.json so that doesn't get secretly-remapped for you and maybe that works

Maybe none of it works, I dunno, but those are things I'd try

@SKempin
Copy link
Author

SKempin commented Oct 15, 2024

Thanks will try the above.

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

No branches or pull requests

3 participants