Skip to content

initializeAuth() crashes on Expo SDK 53 + Hermes with "INTERNAL ASSERTION FAILED: Expected a class definition" #9020

Open
@aaronrk1997

Description

@aaronrk1997

Operating System

MACOS 15.0.1

Environment (if applicable)

Expo SDK 53 (React Native 0.73 / Hermes enabled by default)

Firebase SDK Version

11.7.1

Firebase SDK Product(s)

Auth

Project Tooling

  • Firebase SDK: [email protected]
  • React Native: via Expo SDK 53 (React Native 0.73)
  • JavaScript Engine: Hermes (default enabled in Expo 53)
  • Platform: iOS & Android (Expo Dev Client and EAS Build)
  • Bundler: Metro (default from Expo)
  • Metro config patch:
    • config.resolver.unstable_enablePackageExports = false
    • config.resolver.sourceExts.push('cjs')
  • Expo CLI: 6.x
  • Node.js: 20.x
  • Firebase Auth Persistence Attempted:
    • initializeAuth() with customAsyncStoragePersistence (fails)
    • getAuth() fallback (no crash, but no persistence)

Detailed Problem Description

🧨 Detailed Problem Description

When using initializeAuth() from the modular Firebase Auth SDK ([email protected]) in a React Native project via Expo SDK 53 (with Hermes enabled by default), the application crashes at runtime on native platforms (iOS and Android) with the following error:

@firebase/auth: Auth (11.7.1): INTERNAL ASSERTION FAILED: Expected a class definition
Error: INTERNAL ASSERTION FAILED: Expected a class definition, js engine: hermes

This happens even when:

  • initializeAuth() is wrapped in a Platform.OS !== "web" conditional

  • initializeAuth() is lazy-loaded using import("firebase/auth")

  • The Metro bundler is patched using:

    config.resolver.unstable_enablePackageExports = false;
    config.resolver.sourceExts.push("cjs");
  • Using a dev client or EAS build (not just Expo Go)

  • Firebase is downgraded to v10.11.0 (same crash)

In contrast, using getAuth(app) alone does not crash, but results in non-persistent authentication state on native platforms.


🔍 Additional Notes

  • This issue blocks any use of native persistent auth in Firebase Auth when using Expo SDK 53 and Hermes.
  • Replacing initializeAuth() with getAuth() only avoids the crash at the cost of degraded functionality.
  • The same code worked prior to Expo SDK 53 (e.g. SDK 52 + JSC).
  • No issue occurs in Expo Web or when switching the JS engine to JSC in app.json, but only in custom clients — Expo Go still uses Hermes.

Steps and code to reproduce issue

Steps to Reproduce

  1. Create a new Expo project with SDK 53 and Hermes enabled (default):

    npx create-expo-app firebase-crash-test
    cd firebase-crash-test
    npx expo install firebase
  2. Set up firebaseConfig.ts with the following code:

    // firebaseConfig.ts
    import { initializeApp, getApps, getApp } from "firebase/app";
    import { getAuth } from "firebase/auth";
    import { Platform } from "react-native";
    
    const firebaseConfig = {
      apiKey: "demo",
      authDomain: "demo.firebaseapp.com",
      projectId: "demo",
      storageBucket: "demo.appspot.com",
      messagingSenderId: "123",
      appId: "123:web:demo",
    };
    
    const app = getApps().length ? getApp() : initializeApp(firebaseConfig);
    let auth = getAuth(app);
    
    if (Platform.OS !== "web") {
      import("firebase/auth")
        .then(({ initializeAuth }) => {
          try {
            initializeAuth(app, {
              persistence: require("./asyncStoragePersistence").customAsyncStoragePersistence,
            });
          } catch (e: any) {
            if (e.code !== "auth/already-initialized") throw e;
          }
        })
        .catch((err) => {
          console.error("Firebase native auth init error:", err);
        });
    }
    
    export { app, auth };
  3. Create a dummy asyncStoragePersistence.ts file:

    // asyncStoragePersistence.ts
    import { getReactNativePersistence } from "firebase/auth/react-native";
    import AsyncStorage from "@react-native-async-storage/async-storage";
    
    export const customAsyncStoragePersistence = getReactNativePersistence(AsyncStorage);
  4. Use auth anywhere in your app (e.g., in App.tsx).

  5. Run the app on Android/iOS using a dev client or EAS build:

    npx expo run:android

Result

The app crashes at runtime with this error:

@firebase/auth: Auth (11.7.1): INTERNAL ASSERTION FAILED: Expected a class definition
Error: INTERNAL ASSERTION FAILED: Expected a class definition, js engine: hermes

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions