Open AvilaAi opened 4 years ago
problem solved, just use
firebase
.firestore()
.collection("film")
instead of
const db= firebase.firestore()
db.collection("film")..
Didn't work for me.
Similar problem occurred when building.
firebase.auth()
WebpackError: TypeError: gatsby_plugin_firebase__WEBPACK_IMPORTED_MODULE_1__.default.auth is not a function
I can fix it by adding import "firebase/auth"
, but that was not specified in the document.
I am running into the same problem, but with any of the services (ie firebase.messaging()
, firebase.firestore()
, ect).
My project's gatsby-browser.js
file:
import "firebase/auth";
import "firebase/firestore";
import "firebase/messaging";
import "firebase/functions";
My Gatsby page which uses the Firebase plugin:
import firebase from "gatsby-plugin-firebase";
const Page = () => {
firebase.firestore();
};
export default Page;
When I run gatsby develop
my page everything works.
However when I run gatsby build
(For production) I get the error above.
I added a console.log
statement to node_modules/gatsby-plugin-firebase/src/firebase.js
at the top after the imports and:
console.log("FIREBASE.APPS=", firebase.apps);
and the output is: FIREBASE.APPS= []
.
Not sure why it is working in the development builds but not production builds...
None of the fixes suggested above work either.
I went through all the trouble of using Firebase in my app without this plugin, and then I got the same error. So this must be related to the way Firebase is imported or used generally...
Ok I found 2 definite fixes.
As far as I can tell the reason this is happening is that during the build HTML stage the imports you put in your own gatsby-browser.js
and gatsby-ssr.js
files are not used. Because we are in the NodeJs environment. As a result all the Firebase API client factory methods like firebase.auth()
, firebase.functions()
, ect are not available.
Wrap your usage of Firebase in useEffect(). If you can't use useEffect() then make your component not use Firebase at all if Gatsby is in the build HTML stage.
If you can't use useEffect() then do something like this:
import React from "react";
import firebase from "gatsby-plugin-firebase";
import { isNode } from "@firebase/util";
const FirebaseContext = React.creactContext({});
const FirebaseProvider = ({children}) => {
// If in the Gatsby build HTML stage
// don't do anything with Firebase
if (isNode() === true) {
return children;
}
// Otherwise, use Firebase normally
return (
<FirebaseContext.Provider value={{
functions: firebase.functions(),
auth: firebase.auth()
}}>
{children}
</FirebaseContext.Provider>
);
};
Don't use Firebase in the render() method. In my case moved my usage to the componentDidMount() method and the problem was fixed.
Can confirm this is also an issue for me.
Noah's answer is spot-on. I don't really have anything else to add.
Let me know if what they said doesn't work for you and I can answer on a more case-by-case basis. Thanks folks!
One issue is that I'm using this with the react firebase hooks package. This problem changes my nice one line into an absolute mess, because hooks can't be used in useEffect callbacks.
const [user, loading, error] = useAuthState(firebase.auth())
I might just fork that package and edit it to make the changes there.
Yeah, in this use case I don't think there's anything I can do to help with the integration with react-firebase-hooks
. May worth opening an issue over there?
I decided to just fork it and make it compatible: react-gatsby-firebase-hooks
Whatever I tried just broke it more and more... I just used useEffect
in the end.
I'm still having issues with this even after reformatting my code to match @Noah-Huppert's.
My code works in development but throws an error that one of my context functions is not actually a function when I call isLoggedIn in my header component. Even with the isNode() code, Gatsby tries to access stuff from my Firebase context during the static page generation. Would appreciate any help with this:
Firebase Provider
Header
Error
Clean code for auth:
import React, { useState, useEffect } from 'react';
import firebase from 'gatsby-plugin-firebase';
export default () => {
const { auth } = firebase;
const [user, setUser] = useState();
useEffect(() => auth().onAuthStateChanged(setUser), []);
const login = () => auth().signInWithPopup(new auth.GoogleAuthProvider());
const logout = () => auth().signOut();
if (!user) return <div>no user :/</div>;
const { isAnonymous, displayName } = user;
return (
<div>You logged in as {isAnonymous ? 'Anonymous' : displayName}. {isAnonymous
? <Button onClick={login}>login with Google</Button>
: <Button onClick={logout}>Logout</Button>}
</div>
);
};
I am having issues now with the library 'react-firebase-hooks', where even in gatsby develop firestore is not a function.
@Noah-Huppert Thanks for the fix you suggested. Worked great for me! 🙌🏽
I have a small addition - when you're using the FirebaseContext
in combination with react-firebase-hooks
, gatsby build
will still complain if you haven't provided a value via the FirebaseContext.Provider
.
I was able to get past that by providing a no-op firebase
object like so:
const NoOpFirebase = {
firestore: () => ({
collection: () => ({
where: () => null
})
})
}
export const FirebaseProvider = ({children}) => {
// If in the Gatsby build HTML stage
// don't do anything with Firebase
if (isNode() === true) {
return (
<FirebaseContext.Provider value={NoOpFirebase}>
{children}
</FirebaseContext.Provider>
);
}
// Otherwise, use Firebase normally
return (
<FirebaseContext.Provider value={firebase}>
{children}
</FirebaseContext.Provider>
);
};
I'm trying to use firestore and have imported it in both brower.js and ssr.js, it works in develop, but i got this issue when build:
As mentioned in another issue that no need to import the pacakge in ssr.js, i tried but still not working, anyone can help? thanks