使用 gatsby 解决 netlify 上的 firebase 身份验证(谷歌登录)部署错误

Posted

技术标签:

【中文标题】使用 gatsby 解决 netlify 上的 firebase 身份验证(谷歌登录)部署错误【英文标题】:Resolve firebase authentication (google signIn) deploy error on netlify with gatsby 【发布时间】:2021-07-13 07:43:31 【问题描述】:

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

我正在为我的项目使用 firebase 在 gatsby 中添加 google 登录。 在本地它工作正常,但我似乎无法在 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

我在 env 变量之前添加了 GATSBY_ 前缀

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

在添加 null 以避免 s-s-r 中断后,我收到此错误。

【问题讨论】:

问题可能出在代码“WebpackError: ReferenceError: fetch is not defined”上。您是否导入了 fetch,或者您没有将其用作全局变量。 另外,除非您正在建立用户群,否则我看不出使用 firebase 的理由。无论如何,请检查代码,查看“获取”的定义位置。可能是一个未导入的包,也可能是一个局部变量,如果是的话,让它成为一个全局变量 如何导入 fetch? 使用这个 const fetch = require('node-fetch'); 在 gastby-node.js 中?? 【参考方案1】:

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

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

正如我所说,您的项目在本地运行良好,但如果您只是以相同的命名上传它,Netlify 还没有访问这些变量的权限。正如您在Netlify's docs about Gatsby 中看到的那样:

任何以GATSBY_ 为前缀的environment variables 都由 Gatsby 并在浏览器中提供客户端 javascript 使用权。访问Gatsby docs about environment variables了解更多信息 信息。

您需要在所有环境变量前面加上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中添加如下sn-p:

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

这会将null 加载程序添加到 Firebase 以避免 s-s-r 中断。

关于新问题:

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

【讨论】:

你能详细说明你的答案吗?你试过什么?你清理缓存了吗?它仍然在本地构建吗?正如您在文档中看到的那样,解决方案就是这个。重命名环境变量以使其可被 Netlify 使用。 我添加了一个基于github.com/gatsbyjs/gatsby/issues/29012 的新sn-p 以避免s-s-r 中断。需要保留之前的配置(我们到目前为止所做的) 你检查过***.com/questions/48592656/… 吗?和***.com/questions/58246333/… 关键部分是:typeof window !== 'undefined' if (!firebase) return; 在 firebase 初始化时包装你的逻辑

以上是关于使用 gatsby 解决 netlify 上的 firebase 身份验证(谷歌登录)部署错误的主要内容,如果未能解决你的问题,请参考以下文章

通过 github.io 渲染静态网页不起作用 - 对于使用 gatsby 创建的网站/从 github repo 托管在 netlify 上的网站

如何设置阻止恶意网站转发到我的网站(我的网站建立在 gatsby 上并托管在 netlify 上)

将 Gatsby + Contentful 网站部署到 Netlify

Gatsby + contentful + Netlify 的私人/登录部分

将 Gatsby 博客部署到 Netlify 时出错

使用 Netlify 和 Gatsby 减少初始服务器响应时间