THE PROBLEM
When I run the command:
npx expo run:android
or
npx expo start --reset-cache
My Android Cellphone is connected on my USB port.
I get this error: firebase.auth().useEmulator() takes a non-empty string URL
I suspect the Android app running on my Cellphone can't reach the computer IP using USB.
Or the problem is in the types' definition .d.ts, but I don't have any idea how to solve the signatures of the method useEmulator()
Without the command for emulators the app works connecting to firebase.
console error:
› Logs for your project will appear below. Press Ctrl+C to exit.
Android Bundled 754ms node_modules/expo-router/entry.js (1222 modules)
ERROR Error: firebase.auth().useEmulator() takes a non-empty string URL
This error is located at:
in TabTwoScreen
in Unknown (created by Route(explore))
in Suspense (created by Route(explore))
in Route (created by Route(explore))
in Route(explore) (created by SceneView)
in StaticContainer
in EnsureSingleNavigator (created by SceneView)
in SceneView (created by BottomTabView)
in RCTView (created by View)
in View (created by Screen)
in RCTView (created by View)
in View (created by Background)
in Background (created by Screen)
in Screen (created by BottomTabView)
in RNSScreen (created by Animated(Anonymous))
in Animated(Anonymous) (created by InnerScreen)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by InnerScreen)
in InnerScreen (created by Screen)
in Screen (created by MaybeScreen)
in MaybeScreen (created by BottomTabView)
in RNSScreenContainer (created by ScreenContainer)
in ScreenContainer (created by MaybeScreenContainer)
in MaybeScreenContainer (created by BottomTabView)
in RCTView (created by View)
in View (created by SafeAreaProviderCompat)
in SafeAreaProviderCompat (created by BottomTabView)
in BottomTabView (created by BottomTabNavigator)
in PreventRemoveProvider (created by NavigationContent)
in NavigationContent
in Unknown (created by BottomTabNavigator)
in BottomTabNavigator
in Unknown (created by TabLayout)
in TabLayout
in Unknown (created by Route((tabs)))
in Suspense (created by Route((tabs)))
in Route (created by Route((tabs)))
in Route((tabs)) (created by SceneView)
in StaticContainer
in EnsureSingleNavigator (created by SceneView)
in SceneView (created by SceneView)
in RCTView (created by View)
in View (created by DebugContainer)
in DebugContainer (created by MaybeNestedStack)
in MaybeNestedStack (created by SceneView)
in RCTView (created by View)
in View (created by SceneView)
in RNSScreen (created by Animated(Anonymous))
in Animated(Anonymous) (created by InnerScreen)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by InnerScreen)
in InnerScreen (created by Screen)
in Screen (created by SceneView)
in SceneView (created by NativeStackViewInner)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by ScreenStack)
in RNSScreenStack (created by ScreenStack)
in ScreenStack (created by NativeStackViewInner)
in NativeStackViewInner (created by NativeStackView)
in RCTView (created by View)
in View (created by SafeAreaProviderCompat)
in SafeAreaProviderCompat (created by NativeStackView)
in NativeStackView (created by NativeStackNavigator)
in PreventRemoveProvider (created by NavigationContent)
in NavigationContent
in Unknown (created by NativeStackNavigator)
in NativeStackNavigator
in Unknown (created by RootLayout)
in ThemeProvider (created by RootLayout)
in RootLayout
in Unknown (created by Route())
in Suspense (created by Route())
in Route (created by Route())
in Route() (created by ContextNavigator)
in RNCSafeAreaProvider (created by SafeAreaProvider)
in SafeAreaProvider (created by wrapper)
in wrapper (created by ContextNavigator)
in EnsureSingleNavigator
in BaseNavigationContainer
in ThemeProvider
in NavigationContainerInner (created by ContextNavigator)
in ContextNavigator (created by ExpoRoot)
in ExpoRoot (created by App)
in App (created by ErrorOverlay)
in ErrorToastContainer (created by ErrorOverlay)
in ErrorOverlay (created by withDevTools(ErrorOverlay))
in withDevTools(ErrorOverlay)
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in main(RootComponent), js engine: hermes
ERROR Error: firebase.auth().useEmulator() takes a non-empty string URL
CONFIGURATIONS
npm modules started:
npx expo install firebase
npx expo install @react-native-firebase/app
npx expo install @react-native-firebase/auth
FIREBASE SETUP:
firebase init
EMULATOR SETUP:
firebase init emulators
I started my emulators:
firebase emulators:start
PROJECT SETUP:
android/build.gradle
dependencies {
classpath('com.google.gms:google-services:4.4.2')
}
android/app/build.gradle
apply plugin: 'com.google.gms.google-services'
firebaseConfig.js
import { initializeApp } from 'firebase/app';
// Optionally import the services that you want to use
// import {...} from "firebase/auth";
// import {...} from "firebase/database";
// import {...} from "firebase/firestore";
// import {...} from "firebase/functions";
// import {...} from "firebase/storage";
// Initialize Firebase
const firebaseConfig = {
apiKey: '....',
authDomain: '.....firebaseapp.com',
projectId: '.....',
storageBucket: "......firebasestorage.app",
messagingSenderId: "......",
appId: "1:......:web:......"
};
const app = initializeApp(firebaseConfig);
The root folder has the firebase.json configured
my android folder has:
google-services.json
debug.keystore
my project settings in firebase console and my debug.keystore have the same SHA1.
app.json
{
"expo": {
"plugins": [
"@react-native-firebase/app",
"@react-native-firebase/auth",
"expo-router"
],
}
}
explore.tsx
import auth from '@react-native-firebase/auth';
export default function TabTwoScreen() {
const fire = auth()
fire.useEmulator("192.168.1.26:9099")
}
I tried using:
fire.useEmulator("localhost:9099")
And tried using:
fire.useEmulator("10.0.2.2:9099")
As shown in your screenshot, you are hitting the exception thrown by this validation check:
useEmulator(url) {
if (!url || !isString(url) || !isValidUrl(url)) {
throw new Error('firebase.auth().useEmulator() takes a non-empty string URL');
}
// ...
}
Feeding this function the value 192.168.1.26:9099
passes the !url
and !isString(url)
checks.
But if we take a closer look at the implementation of isValidUrl
, we can see where things go awry:
/**
* URL test
* @param url
* @returns {boolean}
*/
const IS_VALID_URL_REGEX = /^(http|https):\/\/[^ "]+$/;
export function isValidUrl(url) {
return IS_VALID_URL_REGEX.test(url);
}
Based on this regular expression, we can see that the provided URL must start with http://
or https://
followed by some additional characters that are not spaces or double-quote characters.
This means you should be using the string http://192.168.1.26:9099
as the URL, assuming that 192.168.1.26
is the IP address of your computer hosting the emulators.