If you’re building a mobile app with React Native, Expo, and Firebase Authentication, you might encounter the frustrating error: “Component auth has not been registered yet, js engine: hermes” on app launch. This issue often appears after upgrading to Expo SDK 53 or using Firebase’s JavaScript SDK (version 11.x.x or higher). Don’t worry—this comprehensive guide will explain why this error happens, how to fix it, and how to prevent it.
This article covers everything from diagnosing the issue to implementing solutions, complete with code examples, troubleshooting tips, and best practices for React Native Expo Firebase Authentication. Whether you’re a beginner or an experienced developer, you’ll find clear, actionable steps to get your app running smoothly.
What Causes the “Component auth has not been registered yet” Error?
This error typically occurs when the Firebase Authentication module fails to initialize properly in a React Native app built with Expo. The root cause often lies in how the Metro bundler (Expo’s default JavaScript bundler) resolves Firebase’s CommonJS (.cjs) files, especially after updates in Expo SDK 53 or Firebase JS SDK 11.x.x. Here are the main reasons this happens:
- Metro’s Package Exports Handling: Expo SDK 53 introduced support for the
package.json
exports field, which can conflict with Firebase’s modular structure, preventing theauth
component from registering correctly. - Incorrect Firebase SDK Usage: Mixing the Firebase JS SDK (
firebase
) with the React Native Firebase library (@react-native-firebase/*
) can cause conflicts, leading to this error. - AsyncStorage Issues: Firebase Auth requires
@react-native-async-storage/async-storage
for persistence in React Native, and misconfiguration can trigger the error. - Outdated Dependencies or Cache: Stale caches or mismatched dependency versions can prevent proper module resolution.
- Routing Misconfiguration: In apps using Expo Router, improper route setups (e.g., missing default exports in route files) can confuse Metro and trigger this error.
Let’s dive into the solutions, starting with the most effective fixes based on recent community insights and official documentation.
Step-by-Step Solutions to Fix the Error
Here are proven solutions to resolve the “Component auth has not been registered yet” error in your React Native Expo app with Firebase Authentication. Try these in order, testing your app after each step.
Solution 1: Update Metro Config for Firebase Compatibility
The most common fix is to modify your Metro configuration to handle Firebase’s .cjs
files and disable the package.json
exports field, which causes conflicts in Expo SDK 53.
Steps:
- Locate or Create metro.config.js: In your project’s root directory, check for a
metro.config.js
file. If it doesn’t exist, create one. - Update the Config: Add the following code to ensure Metro resolves
.cjs
files and disables theexports
field:
const { getDefaultConfig } = require('expo/metro-config');
module.exports = (() => {
const config = getDefaultConfig(__dirname);
const { resolver } = config;
config.resolver.sourceExts.push('cjs'); // Add support for .cjs files
config.resolver.unstable_enablePackageExports = false; // Disable package.json exports
return config;
})();
- Clear Metro Cache: Run the following command to clear the cache and restart the development server:
npx expo start --clear
- Test Your App: Launch your app using
expo start
orexpo run:android
/expo run:ios
if using a development build.
Why This Works: The Firebase JS SDK uses CommonJS modules (.cjs
) for React Native, and Metro’s default handling of the exports
field in Expo SDK 53 can fail to resolve these modules correctly. Adding .cjs
to sourceExts
and disabling unstable_enablePackageExports
ensures proper module resolution.
Solution 2: Verify Firebase Initialization
Incorrect Firebase setup can cause the auth
component to fail registration. Ensure you’re initializing Firebase correctly with the singleton pattern and using @react-native-async-storage/async-storage
for persistence.
Steps:
- Install AsyncStorage: If not already installed, add the AsyncStorage package:
npm install @react-native-async-storage/async-storage
- Update firebase.js: In your Firebase configuration file (e.g.,
firebase.js
orconfig/firebase.ts
), use the following setup:
import { initializeApp, getApps } from 'firebase/app';
import { initializeAuth, getReactNativePersistence } from 'firebase/auth';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { getFirestore } from 'firebase/firestore';
const firebaseConfig = {
apiKey: 'YOUR_API_KEY',
authDomain: 'YOUR_AUTH_DOMAIN',
projectId: 'YOUR_PROJECT_ID',
storageBucket: 'YOUR_STORAGE_BUCKET',
messagingSenderId: 'YOUR_MESSAGING_SENDER_ID',
appId: 'YOUR_APP_ID',
};
// Initialize Firebase only if no apps are initialized
const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];
// Initialize Auth with AsyncStorage persistence
export const auth = initializeAuth(app, {
persistence: getReactNativePersistence(AsyncStorage),
});
// Initialize Firestore (optional)
export const firestore = getFirestore(app);
- Check for Multiple Initializations: Ensure you’re not calling
initializeAuth
orgetAuth
multiple times in your codebase, as this can cause conflicts. Use a singlefirebase.js
file to export theauth
instance and import it wherever needed. - Test Again: Clear the cache (
npx expo start --clear
) and run your app.
Why This Works: The singleton pattern prevents multiple Firebase app instances, and getReactNativePersistence
ensures auth state persists across sessions, which is critical for React Native.
Solution 3: Remove Conflicting Firebase Libraries
Using both the Firebase JS SDK (firebase
) and React Native Firebase (@react-native-firebase/*
) in the same project can cause the error. You must choose one SDK. For Expo apps, the Firebase JS SDK is recommended unless you need native-specific features like Crashlytics.
Steps:
- Check package.json: Open your
package.json
and look for dependencies like@react-native-firebase/app
or@react-native-firebase/auth
. - Uninstall React Native Firebase: If present, remove these dependencies:
npm uninstall @react-native-firebase/app @react-native-firebase/auth
- Verify Firebase JS SDK: Ensure you have the Firebase JS SDK installed:
npm install firebase@11.7.3
- Remove google-services.json: If you previously used React Native Firebase, delete the
google-services.json
(Android) andGoogleService-Info.plist
(iOS) files from your project, as they’re not needed for the JS SDK. - Clean and Rebuild:
rm -rf node_modules package-lock.json npm install npx expo start --clear
Why This Works: The two Firebase libraries are incompatible and can cause module resolution conflicts, leading to the auth
component error. Sticking to the JS SDK simplifies setup for Expo apps.
Solution 4: Fix Expo Router Configuration
If you’re using Expo Router, the error might stem from misconfigured routes, such as missing default exports in files like register.tsx
or _layout.tsx
.
Steps:
- Check Route Files: Ensure all route files in your
app/
directory have a default export. For example, inapp/(auth)/register.tsx
:import React from 'react'; import { View, Text } from 'react-native'; export default function Register() { return ( <View> <Text>Register Screen</Text> </View> ); }
- Verify Layout Files: Ensure
_layout.tsx
has a default export, like:import { Slot } from 'expo-router'; export default function RootLayout() { return <Slot />; }
- Remove Extraneous Routes: If you see warnings like “Route ‘register’ is extraneous,” check for duplicate or unused routes in your
app/
directory and remove them. - Test Routing: Run
npx expo start --clear
to verify navigation works without errors.
Why This Works: Expo Router requires proper default exports for all route components. Missing exports can confuse Metro, triggering the auth
error.
Solution 5: Downgrade or Pin Firebase Version
Some developers report that downgrading the Firebase JS SDK to a specific version (e.g., 10.x.x) resolves the issue, as newer versions (11.x.x) introduced changes that conflict with Expo SDK 53.
Steps:
- Uninstall Current Firebase:
npm uninstall firebase
- Install a Specific Version:
npm install firebase@10.12.2
- Update Firebase Imports: Ensure your
firebase.js
usesgetAuth
instead ofinitializeAuth
for older versions:import { initializeApp, getApps } from 'firebase/app'; import { getAuth } from 'firebase/auth'; import AsyncStorage from '@react-native-async-storage/async-storage'; const firebaseConfig = { /* your config */ }; const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0]; export const auth = getAuth(app);
- Clean and Test:
rm -rf node_modules package-lock.json npm install npx expo start --clear
Why This Works: Older Firebase versions avoid the .cjs
module issues introduced in newer releases, making them more compatible with Expo SDK 53.
Additional Troubleshooting Tips
If the above solutions don’t work, try these additional checks:
- Clear All Caches: Beyond Metro, clear npm/yarn cache and reset your project:
npm cache clean --force npx expo start --clear npx expo prebuild --clean
- Check for Circular Imports: Ensure your
firebase.js
file isn’t imported in a way that creates circular dependencies. Use a linter like ESLint to detect these. - Verify Node.js Version: Use Node.js 18.x or 20.x, as newer versions (e.g., 22.x) may cause compatibility issues.
- Disable New Architecture: Expo SDK 53’s new Fabric architecture can conflict with Firebase. Disable it in
app.json
:{ "expo": { "experiments": { "newArchitecture": false } } }
- Test on a Fresh Project: Create a new Expo project (
npx create-expo-app
) and replicate your Firebase setup to isolate the issue.
Best Practices for Firebase Auth in Expo
To prevent this error and ensure a smooth Firebase Authentication setup, follow these blogging tips for React Native developers:
- Use the Firebase JS SDK: Stick to
firebase
for Expo apps unless you need native-specific features. - Always Clear Cache After Updates: Run
npx expo start --clear
after changing dependencies or configs. - Follow Singleton Pattern: Initialize Firebase once in a dedicated
firebase.js
file and export services likeauth
andfirestore
. - Keep Dependencies Updated: Regularly check for updates to
expo
,firebase
, and@react-native-async-storage/async-storage
usingnpm outdated
. - Test on Real Devices: Simulators can sometimes mask issues. Use a development build (
npx expo run:android
ornpx expo run:ios
) for accurate testing.
Example: Complete Firebase Auth Setup
Here’s a full example of a working Firebase Authentication setup with Expo SDK 53, including a login screen and auth state management:
// firebase.js
import { initializeApp, getApps } from 'firebase/app';
import { initializeAuth, getReactNativePersistence } from 'firebase/auth';
import AsyncStorage from '@react-native-async-storage/async-storage';
const firebaseConfig = { /* your config */ };
const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];
export const auth = initializeAuth(app, {
persistence: getReactNativePersistence(AsyncStorage),
});
// AuthContext.js ascended
import React, { createContext, useState, useEffect } from 'react';
import { onAuthStateChanged } from 'firebase/auth';
import { auth } from './firebase';
export const AuthContext = createContext({});
export function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const unsub = onAuthStateChanged(auth, (u) => {
setUser(u);
setLoading(false);
});
return unsub;
}, []);
return (
<AuthContext.Provider value={{ user, loading }}>
{children}
</AuthContext.Provider>
);
}
// App.jsx
import React from 'react';
import { View, Text, TextInput, Button } from 'react-native';
import { AuthProvider, AuthContext } from './AuthContext';
import { signInWithEmailAndPassword } from 'firebase/auth';
import { auth } from './firebase';
function LoginScreen() {
const { user } = React.useContext(AuthContext);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleLogin = () => {
signInWithEmailAndPassword(auth, email, password)
.then(() => alert('Logged in!'))
.catch((error) => alert(error.message));
};
return (
<View>
<TextInput
placeholder="Email"
value={email}
onChangeText={setEmail}
/>
<TextInput
placeholder="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<Button title="Log In" onPress={handleLogin} />
</View>
);
}
export default function App() {
return (
<AuthProvider>
<LoginScreen />
</AuthProvider>
);
}
Metro Config (ensure this is in metro.config.js
as shown in Solution 1).
This setup uses the Context API to manage auth state and provides a simple login screen.
Common FAQs
Why does this error only appear on mobile and not the web?
The Firebase JS SDK uses different module resolution for web (ESM) versus React Native (CommonJS). The .cjs
files used in React Native can conflict with Metro’s bundler in Expo SDK 53, causing the error on mobile but not web.
Can I use React Native Firebase instead?
Yes, but it requires native code and isn’t compatible with Expo Go. Use a development build and follow the React Native Firebase setup guide.
How do I know if I have conflicting Firebase libraries?
Check your package.json
for both firebase
and @react-native-firebase/*
. Remove one to avoid conflicts.
What if I’m using TypeScript?
Ensure your TypeScript config (tsconfig.json
) includes "module": "commonjs"
and "allowJs": true
to handle Firebase’s .cjs
files.
Conclusion: Get Your App Back on Track
The “Component auth has not been registered yet” error in React Native Expo with Firebase Auth can be frustrating, but it’s fixable with the right steps. By updating your Metro config, ensuring proper Firebase initialization, removing conflicting libraries, and verifying Expo Router setups, you can resolve the issue quickly. Always test after each change and follow best practices to prevent future errors.
Ready to fix your app? Start with Solution 1 (Metro config update) and work through the steps. If you’re still stuck, share your setup details in the comments, and I’ll help troubleshoot!
Resource:
- For more on Firebase with Expo, check out the Expo Firebase Documentation.
- How Firebase Studio Uses Gemini AI to Revolutionize App Development
- JavaScript Source Code Protection Through Obfuscation