I have a problem while running gatsby build
at the Building static html step. I'm working with gatsby for the frontend and firebase for the backend. I have this error :
ERROR #95313
Building static HTML failed
See our docs page for more info on this error: https://gatsby.dev/debug-html
85 | ]);
86 |
> 87 | proxyRequestMethods(Index, '_index', IDBIndex, [
| ^
88 | 'get',
89 | 'getKey',
90 | 'getAll',
WebpackError: ReferenceError: IDBIndex is not defined
I think the problem comes from my firebase.js file, because when i comment it, the error no longer appears. Here it is :
import firebase from "firebase"
const firebaseConfig = {
apiKey: "AIzaSyDCiX9_kFYoatKJB7Idc-K_k2XrkwUs5So",
authDomain: "gourmeto-6fd67.firebaseapp.com",
databaseURL: "https://gourmeto-6fd67.firebaseio.com",
projectId: "gourmeto-6fd67",
storageBucket: "gourmeto-6fd67.appspot.com",
messagingSenderId: "208164789511",
appId: "1:208164789511:web:22745f19a559f32a"
};
firebase.initializeApp(firebaseConfig)
/*export const googleProvider = new firebase.auth.GoogleAuthProvider()
export const facebookProvider = new firebase.auth.FacebookAuthProvider()
export const auth = firebase.auth()*/
/*export const signOut = () => {
firebase.auth().signOut()
}*/
export default firebase
Thanks for yours answers !
During SSR "browser globals" like window
, document
, or IDBIndex
are undefined. Only browser runtime can truly understand these, as well as, they can hold state specific to currently running page.
To fix you need to ensure code accessing "globals" is not running during build. If it is third-party lib, you can replace that module with empty module.
Here is simplistic example of using gatsby with firebase auth:
1. Replace firebase module with empty module during SSR.
// gatsby-node.js
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
if (stage === "build-html") {
actions.setWebpackConfig({
module: {
rules: [
{
test: /@firebase/,
use: loaders.null(),
},
],
},
})
}
}
2. Do not use directly firebase code eg. use lazy approach
// firebase-wrapper.js
import firebase from 'firebase'
const firebaseConfig = {...}
const lazy = (fn) => {
let isLoaded = false
let result
return () => {
if (!isLoaded) {
isLoaded = true
result = fn()
}
return result
}
}
const app = lazy(() => firebase.initializeApp(firebaseConfig))
const auth = lazy(() => app().auth())
const GoogleAuthProvider = lazy(() => new firebase.auth.GoogleAuthProvider())
export { app, auth, GoogleAuthProvider }
3. Make sure it is called in browser, eg. useEffect, buttonAction, stateInitialization, customProvider or customHook etc
// index.js
import React, {useState, useEffect} from "react"
import {auth, GoogleAuthProvider} from "../firebase-wrapper.js"
const App = () => {
const [user, setUser] = useState(null)
useEffect(()=>{
return auth().onAuthStateChanged(setUser)
})
return (
<div>
<div>User:{user && user.uid}</div>
<button onClick={()=>auth().signInWithPopup(GoogleAuthProvider())}>Sing in with Google</button>
<button onClick={()=>auth().signOut()}>Sign out</button>
</div>
)
}
export default App
There are more approaches to lazy loading like react-loadable, dynamic/lazy imports etc.
See reference Gatsby Docs - Debugging HTML builds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With