Search code examples
javascriptreactjsfirebasegatsbynetlify

Resolve firebase authentication (google signIn) deploy error on netlify with gatsby


Thank you It worked I am pushing my code. You can use it as a reference.

I am using firebase for my project to add google sign in in gatsby.
Locally it works fine but I can't seem to deploy it on netlify.

My Git Repo

I have used gatsby-firebase-plugin but it gives me an error

Warning: This is a browser-targeted Firebase bundle but it appears it is being
12:19:15 AM: run in a Node environment. If running in a Node environment, make sure you
12:19:15 AM: are using the bundle specified by the “main” field in package.json.
12:19:15 AM: If you are using Webpack, you can specify “main” as the first item in
12:19:15 AM: “resolve.mainFields”:
12:19:15 AM: Resolve | webpack
12:19:15 AM: If using Rollup, use the @rollup/plugin-node-resolve plugin and specify “main”
12:19:15 AM: as the first item in “mainFields”, e.g. [‘main’, ‘module’].
12:19:15 AM: https://github.com/rollup/@rollup/plugin-node-resolve
12:19:15 AM: failed Building static HTML for pages - 0.624s
12:19:15 AM: error Building static HTML failed
12:19:15 AM:
12:19:15 AM:
12:19:15 AM: TypeError: Cannot read property ‘split’ of null

Even if I use separate file for firebase like

import firebase from 'firebase';

const firebaseConfig = {
    apiKey: process.env.API_KEY,
    authDomain: process.env.AUTH_DOMAIN,
    projectId: process.env.PROJECT_ID,
    storageBucket: process.env.STORAGE_BUCKET,
    messagingSenderId: process.env.MESSAGING_SENDER_ID,
    appId: process.env.APP_ID
  };

  firebase.initializeApp(firebaseConfig);

export const auth = firebase.auth();

export const provider = new firebase.auth.GoogleAuthProvider();

I get this error

failed Building static HTML for pages - 0.823s
10:21:12 AM: error Building static HTML failed
10:21:12 AM: 
10:21:12 AM:   663 |  * limitations under the License.
10:21:12 AM:   664 |  */
10:21:12 AM: > 665 | registerFunctions(firebase, fetch.bind(self));
10:21:12 AM:       |                           ^
10:21:12 AM:   666 | firebase.registerVersion(name, version);
10:21:12 AM:   667 | //# sourceMappingURL=index.esm.js.map
10:21:12 AM:   668 |
10:21:12 AM: 
10:21:12 AM:   WebpackError: ReferenceError: fetch is not defined

I added GATSBY_ prefix before env variables enter image description here

I also added environment variables in netlify environment enter image description here

After adding null to avoid SSR breaking I am getting this error.

enter image description here


Solution

  • You need to upload your environment variables to Netlify. In addition (and if you've done it), you will need to rename it to make it accessible to Netlify.

    Environment variables in Netlify

    Accessible at: https://app.netlify.com/sites/YOUR_PROJECT_NAME/settings/deploys#environment

    As I said, your project works perfectly locally but Netlify doesn't have access (yet) to those variables if you just upload it with the same naming. As you can see in Netlify's docs about Gatsby:

    Any environment variables prefixed with GATSBY_ are processed by Gatsby and made available in the browser for client-side JavaScript access. Visit the Gatsby docs about environment variables for more information.

    You need to prefix all environment variables with GATSBY_ to make them available. So all your references will became:

    const firebaseConfig = {
        apiKey: process.env.GATSBY_API_KEY,
        authDomain: process.env.GATSBY_AUTH_DOMAIN,
        projectId: process.env.GATSBY_PROJECT_ID,
        storageBucket: process.env.GATSBY_STORAGE_BUCKET,
        messagingSenderId: process.env.GATSBY_MESSAGING_SENDER_ID,
        appId: process.env.GATSBY_APP_ID
      };
    

    Hence the environment files itself, both (.env.development and .env.production) will become:

    GATSBY_API_KEY = 123
    GATSBY_AUTH_DOMAIN = 123
    GATSBY_PROJECT_ID = 123
    GATSBY_STORAGE_BUCKET = 123
    GATSBY_MESSAGING_SENDER_ID = 123
    GATSBY_APP_ID = 123
    

    Now, Netlify will have access to your Firebase initialization and won't break the deployment.

    Summarizing:

    • Upload environment variables to Netlify with GATSBY_ prefix
    • Change all references to the previous environment variables. All variables you want to be readable by Netlify must be prefixed.

    In addition, add the following snippet in the gatsby-node.js:

    exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
      if (stage === "build-html" || stage === "develop-html") {
        actions.setWebpackConfig({
          module: {
            rules: [
              {
                test: /firebase/,
                use: loaders.null(),
              },
            ],
          },
        })
      }
    }
    

    Source: https://github.com/gatsbyjs/gatsby/issues/29012

    This will add a null loader to the firebase to avoid the SSR breaking.

    Regarding the new issue:

    gatsby_plugin_firebase__WEBPACK_IMPORTED_MODULE_4___ default(...).auth

    It should be fixed by:

    import firebase from '@firebase/app';
    import '@firebase/auth';
    import '@firebase/firestore';
    import '@firebase/functions';
    
    const config = {
       ... firebase config here
    };
    
    let instance;
    
    export default function getFirebase() {
      if (typeof window !== 'undefined') {
        if (instance) return instance;
        instance = firebase.initializeApp(config);
        return instance;
      }
    
      return null;
    }
    

    Then, you just can:

    import React { useEffect } from 'react';
    import getFirebase from './firebase';
    
    function MyApp() {
    const firebase = getFirebase();
    
    useEffect(() => {
    if (!firebase) return;
    
    // once your firebase is instanced, use it.
    firebase.auth().onAuthStateChanged((user) => { ... });
    }, [firebase]);
    }