Failed to initialize auth with persistence: [Error: Component auth has not been registered yet]
Operating System
Mac OS
Environment (if applicable)
Expo 52 / React Native
Firebase SDK Version
11.6.1
Firebase SDK Product(s)
Auth
Project Tooling
Environment firebase: 11.6.1 react-native: 0.79.1 expo: 53.0.1 @react-native-async-storage/async-storage: 2.1.2
Detailed Problem Description
When using the Firebase JS SDK ([email protected]) with React Native ([email protected]), initializing Auth without explicitly providing AsyncStorage results in:
The warning appears even though @react-native-async-storage/async-storage is installed. The error [Error: Component auth has not been registered yet] is thrown on initialization. This occurs when using the standard getAuth() import from firebase/auth.
Steps and code to reproduce issue
Install dependencies as above. Initialize Firebase and Auth in a React Native project. Observe the warning and error on app start.
Expected Behavior Auth should initialize without error if AsyncStorage is installed. If AsyncStorage is required, the SDK should detect and use it automatically, or provide clear instructions for React Native users.
I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
I've been using this for the last 2 years with no problems until I upgraded as well. Did I miss something in an update?
File
import AsyncStorage from "@react-native-async-storage/async-storage";
import { initializeApp } from "firebase/app";
import { initializeAuth, getReactNativePersistence } from "firebase/auth";
import getEnvVars from "./Environment";
/** Dynamically fetch environment variables. */
const { ENVIRONMENT } = getEnvVars();
/** Initializes the {@link firebase} application with configuration options. */
const FirebaseApp = initializeApp(
ENVIRONMENT === "production"
? require("./FirebaseConfig.prod.json")
: require("./FirebaseConfig.dev.json"),
);
/**
* This function allows more control over the Auth instance than getAuth, which uses platform-specific defaults to supply the Dependencies.
* In general, getAuth is the easiest way to initialize Auth and works for most use cases. Use initializeAuth if you need control over which
* persistence layer is used, or to minimize bundle size if you're not using either signInWithPopup or signInWithRedirect.
*
* @see https://firebase.google.com/support/release-notes/js#authentication
*/
const FirebaseAuth = initializeAuth(FirebaseApp, {
persistence: getReactNativePersistence(AsyncStorage),
});
/** Export the variables so the rest of the app can have access to them. */
export { FirebaseAuth, FirebaseApp };
I'm using the following related packages
{
"@react-native-async-storage/async-storage": "^2.1.2",
"expo": "^53.0.4",
"firebase": "^11.6.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-native": "~0.79.2"
}
I tried to use it in my React Native Expo project with Expo version 53. It causes the same problem. Then I tried with my older project (Expo SDK 52) and then it worked. I think the Firebase JS SDK needs an update for Expo SDK 53 and higher.
Here's the bug on the expo side of things. Between firebase or expo, it must be something. I gotta switch off firebase if this continues
https://github.com/expo/expo/issues/36496
Unresolved past issue here https://github.com/firebase/firebase-js-sdk/issues/8798
Im having the same issue, using Expo SDK 53.0.5 and firebase 11.6.1, it works fine on 52
it could possibly be related to metro enabling support for package.json:exports -- https://github.com/expo/expo/discussions/36551. try disabling it as described in that discussion topic
it could possibly be related to metro enabling support for package.json:exports -- expo/expo#36551. try disabling it as described in that discussion topic
Thanks @brentvatne. This resolved the issue for me. I've added it to the list https://github.com/expo/expo/discussions/36551#discussioncomment-13021826
Full explanation about what's going wrong can be found here: https://github.com/expo/expo/issues/36598#issuecomment-2848750540
And a repro can be found here: https://github.com/DavidKellyAD/repro-firebase
Full explanation about what's going wrong can be found here: expo/expo#36598 (comment)
That is a good explanation, but the workaround does not work for me.
Awesome, thanks @byCedric this fixed it for me! Hopefully someone at firebase can implement the suggestions you have to make the repo compatible with react native/expo.
same error with firebase on expo 53
Thanks, @byCedric 's explanation is very helpful, we'll try to see if we can implement one of those options.
for those who're using bare React Native:
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config')
const defaultResolver = require('metro-resolver').resolve
const defaultConfig = getDefaultConfig(__dirname)
const { assetExts, sourceExts } = defaultConfig.resolver
/**
* Metro configuration
* https://reactnative.dev/docs/metro
*
* @type {import('metro-config').MetroConfig}
*/
const config = {
transformer: {
getTransformOptions: async () => ({
transform: { experimentalImportSupport: false, inlineRequires: true },
}),
},
resolver: {
sourceExts: [...sourceExts, 'js', 'ts'],
resolveRequest: (context, moduleName, platform) => {
if (moduleName.startsWith('@firebase/')) {
return defaultResolver({ ...context, isESMImport: true }, moduleName, platform)
}
return defaultResolver(context, moduleName, platform)
},
},
}
module.exports = mergeConfig(defaultConfig, config)
heavily inspired by https://github.com/expo/expo/issues/36598#issuecomment-2848750540 props to @byCedric
Solution :
For Expo:
metro.config.js
const { getDefaultConfig } = require("expo/metro-config");
/** @type {import('expo/metro-config').MetroConfig} */
const defaultConfig = getDefaultConfig(__dirname);
defaultConfig.resolver.unstable_enablePackageExports = false;
module.exports = defaultConfig;
For Bare React Native :
metro.config.js
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
/** @type {import('@react-native/metro-config').MetroConfig} */
const config = {};
const defaultConfig = getDefaultConfig(__dirname);
defaultConfig.resolver.unstable_enablePackageExports = false;
module.exports = mergeConfig(defaultConfig, config);
Other Methods :
Above method worked for me in Bare React Native or You can check and try :
- https://github.com/expo/expo/discussions/36551
- https://github.com/firebase/firebase-js-sdk/issues/8988#issuecomment-2873559711
My dependencies :
In Expo :
"expo": "~52.0.38",
"react-native": "^0.76.7",
"@react-native-async-storage/async-storage": "^1.23.1",
"firebase": "^11.0.2",
In Bare React Native :
"react-native": "0.79.2",
"@react-native-async-storage/async-storage": "^1.24.0",
"firebase": "^11.8.1",
⚠️ I found somewhere (also experimented by myself) that the firebase latest version is having some compatible issues with @react-native-async-storage/async-storage of version >= 2.0.0
@patrickkeenan
Also @brentvatne and @byCedric check the above methods and compatibility issue of firebase and async-storage. And please correct me if I'm wrong. 🙂
Adding config.resolver.unstable_enablePackageExports = false to my existing metro.config.js (which also uses NativeWind) fixed the issue for me. Firebase Auth now initializes without any errors on Expo SDK 53. Thanks for the solution! @I-am-Pritam-20
Suggested Metro Configuration
ES modules (import/export) do not correctly provide the output to metro. "type": "module" does not work. CommonJS is needed.
// metro.config.js
const path = require('path');
const { getDefaultConfig } = require('expo/metro-config');
/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(process.cwd());
// 1. Disable experimental “exports” field resolution
config.resolver.unstable_enablePackageExports = false;
// 2. Recognize CommonJS “.cjs” files
config.resolver.sourceExts.push('cjs');
// 3. (Optional) Define module aliases
const ALIASES = {
tslib: path.resolve(process.cwd(), 'node_modules/tslib/tslib.es6.js'),
};
// 4. Custom resolver to enforce ESM for Firebase and apply aliases
config.resolver.resolveRequest = (context, moduleName, platform) => {
// 4a. Always load Firebase packages as ESM
if (moduleName.startsWith('@firebase/')) {
return context.resolveRequest(
{ ...context, isESMImport: true },
moduleName,
platform
);
}
// 4b. Apply any user-defined aliases
const target = ALIASES[moduleName] || moduleName;
return context.resolveRequest(context, target, platform);
};
module.exports = config;
Things That Don’t Work
1. @react-native-community/cli
- Installing this CLI package can break the Android Gradle build (see StackOverflow).
- Workaround: Remove
@react-native-community/clientirely and rely on Expo’s built-in commands.
2. expo-build-properties
- Adding this plugin often fails to apply Android- or iOS-specific build settings (see expo#26539 and stripe-react-native#1924).
- Workaround: Omit
expo-build-propertiesand rely on the react-native versioning for fixing this error.
3. Kotlin resolver, Google Maven ordering & compileKotlin failure
- Forcing Kotlin to an unpublished version (e.g.
1.9.0or2.1.0) makes Gradle request a POM from Google Maven that doesn’t exist—yet instead of a clear “repository not found” or POM error, you get:
Task \:react-native-gradle-plugin\:compileKotlin FAILED
This hides the real download failure.
- Workaround: React Native determines your Kotlin version, not Expo. Align your React native version to a release that bundles your target Kotlin version. Take a look at the below.
There are likely a number of other potential hazards, such as uuid instead of react-native-uuid. I hope you find this helpful.
Things That Do Work
A. Dependency Health Check
Run:
npx expo-doctor@latest
to diagnose any package mismatches. Then fix them with:
npx expo install --check
This will update your Expo-managed dependencies to the correct, SDK-compatible versions.
B. Locked Package Versions
Ensure your package.json pins only supported versions:
{
"dependencies": {
"expo": "~53.0.11",
"react-native": "^0.79.3", // ⚠️ Do not upgrade to 0.80.x yet
"firebase": "^11.9.1",
"@react-native-async-storage/async-storage": "2.1.2"
}
}
Keeping these versions locked avoids unexpected breaking changes and ensures compatibility across your entire Expo/React Native workflow.
Solution :
For Expo:
metro.config.js
const { getDefaultConfig } = require("expo/metro-config");
/** @type {import('expo/metro-config').MetroConfig} */
const defaultConfig = getDefaultConfig(__dirname); defaultConfig.resolver.unstable_enablePackageExports = false; module.exports = defaultConfig;
For Bare React Native :
metro.config.js
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
/** @type {import('@react-native/metro-config').MetroConfig} */
const config = {}; const defaultConfig = getDefaultConfig(__dirname); defaultConfig.resolver.unstable_enablePackageExports = false; module.exports = mergeConfig(defaultConfig, config);
Other Methods :
Above method worked for me in Bare React Native or You can check and try :
- Libraries that are incompatible with Metro ES Module resolution expo/expo#36551
- Failed to initialize auth with persistence: [Error: Component auth has not been registered yet] #8988 (comment)
My dependencies :
In Expo :
"expo": "~52.0.38", "react-native": "^0.76.7", "@react-native-async-storage/async-storage": "^1.23.1", "firebase": "^11.0.2", In Bare React Native :
"react-native": "0.79.2", "@react-native-async-storage/async-storage": "^1.24.0", "firebase": "^11.8.1", ⚠️ I found somewhere (also experimented by myself) that the firebase latest version is having some compatible issues with @react-native-async-storage/async-storage of version >= 2.0.0
Also @brentvatne and @byCedric check the above methods and compatibility issue of firebase and async-storage. And please correct me if I'm wrong. 🙂
I tried all the settings provided but I still encountered the error "Service firestore is not available".
Solution :
For Expo:
metro.config.js
const { getDefaultConfig } = require("expo/metro-config");
/** @type {import('expo/metro-config').MetroConfig} */
const defaultConfig = getDefaultConfig(__dirname); defaultConfig.resolver.unstable_enablePackageExports = false; module.exports = defaultConfig;
For Bare React Native :
metro.config.js
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
/** @type {import('@react-native/metro-config').MetroConfig} */
const config = {}; const defaultConfig = getDefaultConfig(__dirname); defaultConfig.resolver.unstable_enablePackageExports = false; module.exports = mergeConfig(defaultConfig, config);
Other Methods :
Above method worked for me in Bare React Native or You can check and try :
- Libraries that are incompatible with Metro ES Module resolution expo/expo#36551
- Failed to initialize auth with persistence: [Error: Component auth has not been registered yet] #8988 (comment)
My dependencies :
In Expo :
"expo": "~52.0.38", "react-native": "^0.76.7", "@react-native-async-storage/async-storage": "^1.23.1", "firebase": "^11.0.2", In Bare React Native :
"react-native": "0.79.2", "@react-native-async-storage/async-storage": "^1.24.0", "firebase": "^11.8.1", ⚠️ I found somewhere (also experimented by myself) that the firebase latest version is having some compatible issues with @react-native-async-storage/async-storage of version >= 2.0.0
Also @brentvatne and @byCedric check the above methods and compatibility issue of firebase and async-storage. And please correct me if I'm wrong. 🙂
I tried all the settings provided but I still encountered the error "Service firestore is not available".
@AndreyPassos
-
Check for the initialization of Firebase in your codebase
-
react-native/firebase and firebase package have different approaches of initialization.
-
Make sure your firebase account is up and running and have proper read, write rules set and properly configured in order to be used by your application.
3. Make sure your firebase account is up and running and have proper read, write rules set and properly configured in order to be used by your application.
I have been testing since version 10.12.2 of Firebase. That is the version my app was on, which was a lower version of React Native and it was working. However, I decided to update and now I am having this problem in the more current versions. This is my firebase init: import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
const firebaseConfig = {};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
export default db;
3. Make sure your firebase account is up and running and have proper read, write rules set and properly configured in order to be used by your application.
I have been testing since version 10.12.2 of Firebase. That is the version my app was on, which was a lower version of React Native and it was working. However, I decided to update and now I am having this problem in the more current versions. This is my firebase init: import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
const firebaseConfig = {};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
export default db;
@AndreyPassos
Try this syntax :
import { initializeApp } from 'firebase/app';
import { initializeAuth, getReactNativePersistence } from 'firebase/auth';
// Uses local storage to prevent firebase access frequently on each boot of the app , increased performance , Firebase free plan will not end soon
import ReactNativeAsyncStorage from '@react-native-async-storage/async-storage';
import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
// Optional if you need storage access
import { getStorage } from 'firebase/storage';
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "AUTH_DOMAIN",
databaseURL: "DATABASE_URL",
projectId: "PROJECT_ID",
storageBucket: "STORAGE_BUCKET_ID",
messagingSenderId: "SENDER_ID",
appId: "APP_ID",
};
const app = initializeApp(firebaseConfig);
export const auth = initializeAuth(app, {
persistence: getReactNativePersistence(ReactNativeAsyncStorage),
});
export const db = getFirestore(app);
//Optional if you need storage access
export const storage = getStorage(app);
Other things to check:
-
If you are in Expo managed workflow, make sure the Expo , React native, Async Storage, Firebase - each of them have proper compatible version installed. (Same for Bare React Native )
-
Try building and testing a new project only with these packages installed with cleared npx/ npm cache. (In Bare React Native clear build.gradle cache and try a new build)
-
Network/ Firewall not causing issues with Firebase access
-
Try testing with other solutions provided by the others in this discussion (Some Expo devs also provided solutions in the above discussion column. Make sure to check those as well.)
Issues I got while going through
- Incompatible package versions
I tried to use the same dependencies you gave for using expo, but I haven't succeeded yet. It returned this error now: "Error: Component auth has not been registered yet, js engine: hermes".
"expo": "~52.0.38", "react-native": "^0.76.7", "@react-native-async-storage/async-storage": "^1.23.1", "firebase": "^11.0.2"
I tried to use the same dependencies you gave for using expo, but I haven't succeeded yet. It returned this error now: "Error: Component auth has not been registered yet, js engine: hermes".
"expo": "~52.0.38", "react-native": "^0.76.7", "@react-native-async-storage/async-storage": "^1.23.1", "firebase": "^11.0.2"
Sorry but the error you encountered may occur in the app if you are trying with Bare React Native.
And I think Expo managed workflow will not show such errors. But if showing then check the version compatibilities.
There will be different approaches for Expo managed workflow and Bare React Native workflow. (already mentioned in the previous comments not only by me, but also by other Devs, kindly check all those 🙂).
For Bare React Native try removing build.gradle cache from App level folder as well as Project level folder (if exists), clear npx/npm cache and try rebuilding.
I think this will help. @AndreyPassos