Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot connect to the emulators, (FirebaseError: Expected type 'Firestore$1', but it was: a custom Firestore object) #490

Closed
CuriosBasant opened this issue Nov 29, 2021 · 12 comments

Comments

@CuriosBasant
Copy link

CuriosBasant commented Nov 29, 2021

Version info

React:
17.0.2

Firebase:
9.5.0

ReactFire:
4.2.1

Other (e.g. Node, browser, operating system) (if applicable):
Node16, Chrome, MacOS

Steps to reproduce

I'm using nextjs, in the pages/_app.tsx paste the following code

import { connectAuthEmulator, getAuth } from "@firebase/auth"
import { connectFirestoreEmulator, getFirestore } from "@firebase/firestore"
import { AppProps } from "next/app"
import { AuthProvider, FirebaseAppProvider, FirestoreProvider, useFirebaseApp } from "reactfire"
import "../styles/globals.css"

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <FirebaseAppProvider firebaseConfig={{ projectId: "shadyantra-a75f0", apiKey: "fake-key" }}>
      <FirebaseSDKProviders>
        <Component {...pageProps} />
      </FirebaseSDKProviders>
    </FirebaseAppProvider>
  )
}

function FirebaseSDKProviders({ children }) {
  const app = useFirebaseApp()
  const auth = getAuth(app)
  const firestore = getFirestore(app)

  if (true) {
    connectAuthEmulator(auth, "http://localhost:9099", { disableWarnings: true })
    connectFirestoreEmulator(firestore, "localhost", 8080)
  }

  return (
    <AuthProvider sdk={auth}>
      <FirestoreProvider sdk={firestore}>{children}</FirestoreProvider>
    </AuthProvider>
  )
}

Expected behavior

I should be able to connect to the emulator, without any error

Actual behavior

Right now it is giving me this error, "FirebaseError: Expected type 'Firestore$1', but it was: a custom Firestore object"

image

@jhuleatt
Copy link
Collaborator

@CuriosBasant does this error still happen if you import from firebase/firestore and firebase/auth instead of the @firebase versions? From the @firebase/firestore npm page:

This package is not intended for direct usage, and should only be used via the officially supported firebase package.

If it's still an issue with the main packages, please let us know.

@CuriosBasant
Copy link
Author

CuriosBasant commented Dec 1, 2021

This error is still there, when I first start the application. After doing few refreshes it gets automatically resolved (just randomly). :(

@angelroma
Copy link

@CuriosBasant This is what I did to avoid this error message:


function FirebaseComponents({ children }: { children: React.ReactNode }) {
  const app = useFirebaseApp(); // a parent component contains a `FirebaseAppProvider`
  const auth = getAuth(app);

  const { status, data: firestoreInstance } = useInitFirestore(
    async (firebaseApp) => {
      const db = initializeFirestore(firebaseApp, {});
      return db;
    }
  );

  if (status === "loading") {
    return <div>Loading Firestore...</div>;
  }

  if (process.env.NODE_ENV !== "production") {
    connectAuthEmulator(auth, "http://localhost:9099");
    connectFirestoreEmulator(firestoreInstance, "localhost", 8080);
  }

  return (
    <AuthProvider sdk={auth}>
      <FirestoreProvider sdk={firestoreInstance}>{children}</FirestoreProvider>
    </AuthProvider>
  );
}

@shalomsam
Copy link

@angelroma - is there a working example of how you got this to work? I get the same error.

@aageorge
Copy link

aageorge commented Jan 5, 2022

Also ran into the same issue trying to connect an emulator

  const app = useFirebaseApp();
  const auth = getAuth(app);
  const firestore = getFirestore(app);

  if (process.env.NODE_ENV !== 'production') {
    // Set up emulators
    if (!auth.emulatorConfig) {
      connectAuthEmulator(auth, 'http://localhost:9099');
    }
     connectFirestoreEmulator(firestore, 'localhost',8080);
  }

@aageorge
Copy link

aageorge commented Jan 5, 2022

It may be a limitation in how connectFirestoreEmulator is working, and/or Im not super in depth with each of the application lifecycles. I was able to resolve my issue @shalomsam / @CuriosBasant by wrapping the setup in use effect to await for component init on app

  const app = useFirebaseApp();
  const auth = getAuth(app);
  const firestore = getFirestore(app);
  
  useEffect(() => {
    if (process.env.NODE_ENV !== 'production') {
      // Set up emulators
      if (!auth.emulatorConfig) {
        connectAuthEmulator(auth, 'http://localhost:9099');
      }
        connectFirestoreEmulator(firestore, 'localhost',8080);
    }
  }, [app])

I believe this is more an issue with firebase than reactfire

@CuriosBasant
Copy link
Author

CuriosBasant commented Jan 7, 2022

@aageorge @shalomsam This is what I'm currently doing to get rid of this issue, as @angelroma's solution didn't work for me.

import { app, auth, firestore } from "../firebase/client"

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <FirebaseAppProvider firebaseApp={app}>
      <FirebaseSDKProviders>
        <ThemeProvider>
          <Component {...pageProps} />
        </ThemeProvider>
      </FirebaseSDKProviders>
    </FirebaseAppProvider>
  )
}

function FirebaseSDKProviders({ children }) {
  return (
    <AuthProvider sdk={auth}>
      <FirestoreProvider sdk={firestore}>{children}</FirestoreProvider>
    </AuthProvider>
  )
}

And in "../firebase/client.ts"

import { getApp, getApps, initializeApp } from "firebase/app"
import { connectAuthEmulator, getAuth } from "firebase/auth"
import { connectFirestoreEmulator, getFirestore } from "firebase/firestore"
import { __DEV__ } from "../constants"

if (!getApps().length) {
  const app = initializeApp({
    // firebase project options
  })

  const auth = getAuth(app),
    firestore = getFirestore(app)
    
  if (typeof window != "undefined" && __DEV__) {
    console.info("Dev Env Detected: Using Emulators!")
    const firebaseConfig = require("../../firebase.json")
    if (auth.emulatorConfig?.host !== "localhost")
      connectAuthEmulator(auth, `http://localhost:${firebaseConfig.emulators.auth.port}`, {
        disableWarnings: true,
      })

    // @ts-ignore
    if (!firestore._settings?.host.startsWith("localhost"))
      connectFirestoreEmulator(firestore, "localhost", firebaseConfig.emulators.firestore.port)
  }
}

export const app = getApp()
export const auth = getAuth(app)
export const firestore = getFirestore(app)

ky28059 added a commit to GunnWATT/watt that referenced this issue Feb 19, 2022
This currently suffers from firebase/firebase-js-sdk#6019 and FirebaseExtended/reactfire#490, as well as an unrelated NextJS error.
@usuarez
Copy link

usuarez commented Mar 13, 2022

make sure that u're using firebase/firestore or firebase/firestore/lite in all your firebase imports, is u' can't get data from db using both libs, for example if you:

import { getFirestore } from "firebase/firestore";
the need the correct imports
import { deleteDoc, doc, getDoc, getDocs, onSnapshot, updateDoc } from "firebase/firestore";
but if you
import { deleteDoc, doc, getDoc, getDocs, onSnapshot, updateDoc } from "firebase/firestore/lite";
the error Expected type 'xxxx', but it was: a custom Firestore object appears in your app.

So, use only one lib, it works for me

@CuriosBasant
Copy link
Author

@usuarez Yes I'm totally aware of that. And I can confirm that is not the case.
To solve it, I had to create a separate file, initialise all the sdk's there, and then importing and passing them to the SDK Providers.
As you can see in my above comment

@daryazata
Copy link

@usuarez hei thanks for pointing to this issue, this was the mistake for me... Why in the world autoimport works in first place for firebase/../lite folder but not for the main folder ... thanks I was already giving up on this---

@Jordan6794
Copy link

@usuarez Thanks! I had this issue because of that too

@jhuleatt
Copy link
Collaborator

@usuarez's comment #490 (comment) about mixing firestore and firestore/lite is one possible cause.

Another is by accidentally importing two different versions of the firestore library. This is called the dual package hazard and happens when different dependencies use different versions of the same package due to bundler setup. ReactFire 4.2.2 has a new build process that should lower the chance of this happening.

@FirebaseExtended FirebaseExtended locked and limited conversation to collaborators Sep 17, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants