解决firebase authentication (google signIn) deploy on netlify with gatsby错误

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

谢谢它成功了我正在推送我的代码。可以作为参考。

我正在为我的项目使用 firebase 添加 google 登录 gatsby。
在本地它工作正常,但我似乎无法在 netlify 上部署它。

My Git Repo

我使用了 gatsby-firebase-plugin 但它给我一个错误

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

即使我为 firebase 使用单独的文件,例如

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();

我收到这个错误

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

我在环境变量之前添加了 GATSBY_ 前缀

我还在netlify环境中添加了环境变量

添加 null 以避免 SSR 中断后我收到此错误。

您需要将环境变量上传到 Netlify。此外(如果您已经这样做了),您将需要重命名它以使其可供 Netlify 访问。

访问地址:https://app.netlify.com/sites/YOUR_PROJECT_NAME/settings/deploys#environment

正如我所说,您的项目在本地完美运行,但如果您只是使用相同的命名上传它,Netlify 还无法访问这些变量。正如您在 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.

您需要在所有环境变量前加上 GATSBY_ 前缀才能使它们可用。所以你所有的参考资料都会变成:

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
  };

因此环境文件本身(.env.development.env.production)将变为:

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

现在,Netlify 将可以访问您的 Firebase 初始化并且不会破坏部署。

总结:

  • 使用 GATSBY_ 前缀将环境变量上传到 Netlify
  • 更改对以前环境变量的所有引用。您希望 Netlify 可读的所有变量都必须加上前缀。

此外,在 gatsby-node.js 中添加以下代码段:

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

来源:https://github.com/gatsbyjs/gatsby/issues/29012

这将向 firebase 添加一个 null 加载程序以避免 SSR 中断。

关于新一期:

gatsby_plugin_firebase__WEBPACK_IMPORTED_MODULE_4___ default(...).auth

应该通过以下方法修复:

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;
}

那么,你就可以:

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]);
}