firebase-js-sdk icon indicating copy to clipboard operation
firebase-js-sdk copied to clipboard

Failed to initialize auth with persistence: [Error: Component auth has not been registered yet]

Open patrickkeenan opened this issue 7 months ago • 17 comments

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.

patrickkeenan avatar Apr 30 '25 15:04 patrickkeenan

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

google-oss-bot avatar Apr 30 '25 15:04 google-oss-bot

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"
}

iM-GeeKy avatar May 01 '25 19:05 iM-GeeKy

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.

tanvir-ahmad avatar May 02 '25 08:05 tanvir-ahmad

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

patrickkeenan avatar May 02 '25 11:05 patrickkeenan

Unresolved past issue here https://github.com/firebase/firebase-js-sdk/issues/8798

patrickkeenan avatar May 02 '25 12:05 patrickkeenan

Im having the same issue, using Expo SDK 53.0.5 and firebase 11.6.1, it works fine on 52

Enigma94 avatar May 02 '25 12:05 Enigma94

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

brentvatne avatar May 02 '25 23:05 brentvatne

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

petrusvanegeraat avatar May 03 '25 06:05 petrusvanegeraat

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

byCedric avatar May 03 '25 18:05 byCedric

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.

tetogomez avatar May 03 '25 19:05 tetogomez

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.

patrickkeenan avatar May 04 '25 22:05 patrickkeenan

same error with firebase on expo 53

ottosamatori avatar May 05 '25 11:05 ottosamatori

Thanks, @byCedric 's explanation is very helpful, we'll try to see if we can implement one of those options.

hsubox76 avatar May 06 '25 16:05 hsubox76

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

12ya avatar May 12 '25 18:05 12ya

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. 🙂

I-am-Pritam-20 avatar May 24 '25 13:05 I-am-Pritam-20

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

ktugbaa7 avatar Jun 04 '25 14:06 ktugbaa7

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/cli entirely 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-properties and 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.0 or 2.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.

pranitsh avatar Jun 15 '25 03:06 pranitsh

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 :

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. 🙂

I tried all the settings provided but I still encountered the error "Service firestore is not available".

AndreyPassos avatar Jun 26 '25 00:06 AndreyPassos

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 :

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. 🙂

I tried all the settings provided but I still encountered the error "Service firestore is not available".

@AndreyPassos

  1. Check for the initialization of Firebase in your codebase

  2. react-native/firebase and firebase package have different approaches of initialization.

  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-am-Pritam-20 avatar Jun 26 '25 01:06 I-am-Pritam-20

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 avatar Jun 26 '25 01:06 AndreyPassos

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:

  1. 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 )

  2. 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)

  3. Network/ Firewall not causing issues with Firebase access

  4. 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

  1. Incompatible package versions

I-am-Pritam-20 avatar Jun 26 '25 03:06 I-am-Pritam-20

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"

AndreyPassos avatar Jun 26 '25 15:06 AndreyPassos

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

I-am-Pritam-20 avatar Jun 27 '25 08:06 I-am-Pritam-20