如何在Gatsby中初始化Firebase? [英] How to initialize firebase in gatsby?

查看:85
本文介绍了如何在Gatsby中初始化Firebase?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直坚持在将Redux与Redux-sagas结合使用的gatsby应用程序中使Firebase正常工作.我知道firebase-sagas的存在,但是我试图不使用它.

I'm stuck on making firebase work in my gatsby application that uses Redux with Redux-sagas. I know about the existence of firebase-sagas but I'm trying to make without using it.

我正在尝试通过以下方式初始化Firebase身份验证:

I'm trying to init firebase auth by:

import * as firebase from 'firebase/app';
import 'firebase/auth';

export const app = firebase.initializeApp(
  {
    apiKey        : "apiKey",
    authDomain    : "project.firebaseapp.com",
    databaseURL   : "https://project.firebaseio.com",
    projectId     : "project",
    storageBucket : "project.appspot.com",
    appId         : "appId"
  }

)

export const authRef = () => app.auth(); //also tried: firebase.auth() and firebase.auth(app)
//firebase.auth returns a function, but firebase.auth() throws error

我在gatsby-node.js上具有以下配置:

const path = require('path');

exports.onCreateWebpackConfig = ({ actions, plugins, loaders, getConfig }) => {
  const config = getConfig()

  config.resolve = {
    ...config.resolve,
      mainFields: ['module', 'browser', 'main'],
      alias: {
        ...config.resolve.alias,
        ['firebase/app']       : path.resolve(__dirname, 'node_modules/firebase/app/dist/index.cjs.js'),
        ['firebase/auth']      : path.resolve(__dirname, 'node_modules/firebase/auth/dist/index.cjs.js'),
      }
  }

  actions.replaceWebpackConfig(config)
}

它引发错误:

{ [M [Error]: The XMLHttpRequest compatibility library was not found.]
  code: 'auth/internal-error',
  message: 'The XMLHttpRequest compatibility library was not found.' }

我认为这与webpack有关.我希望对这个问题有任何见解:)

I think it's some problem related to webpack. I would love any insights on this problem :)

推荐答案

由于Gatsby在服务器环境中构建页面,因此在Gatsby构建期间无法访问Firebase.当用户位于浏览器/客户端环境中时,必须进行Firebase调用(使用Web SDK).

As Gatsby builds pages in a server environment, you can't access Firebase during Gatsby build time. Firebase calls (using the Web SDK) have to happen when the user is on a browser/client environment.

解决此问题的一种方法是创建一个像这样的函数:

One solution to this problem is creating a function like so:

firebase.js:

firebase.js:

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

此文件返回一个函数,如果用户具有可用的全局window(例如,在浏览器上),则该函数将返回Firebase的实例.它还会缓存Firebase实例,以确保无法再次对其进行初始化(如果用户更改了您网站上的页面).

This file returns a function, which returns an instance of Firebase if the user has the global window available (e.g. on the browser). It also caches the Firebase instance to ensure it cannot be reinitialised again (in case of the user changing page on your website).

在组件中,您现在可以执行以下操作:

In your components, you can now do something similar to the following:

import getFirebase from './firebase';

function MyApp() {
  const firebase = getFirebase();
}

由于Gatsby将尝试在gatsby build期间将此页面构建为HTML,因此firebase const将返回null,这是正确的,因为Firebase Web SDK无法在服务器环境中初始化.但是,要在您的网站上使用Firebase,您需要等到Firebase可用(因此用户必须已加载您的网站)后,我们才能使用Reacts useEffect钩子:

As Gatsby will try to build this page into HTML during gatsby build, the firebase const will return null, which is correct, as the Firebase Web SDK cannot initialise on a server environment. However, to make use of Firebase on your website, you need to wait until Firebase is available (so the user has to have loaded your website), so we can make use of Reacts useEffect hook:

import React { useEffect } from 'react';    
import getFirebase from './firebase';

function MyApp() {
  const firebase = getFirebase();

  useEffect(() => {
    if (!firebase) return;

    firebase.auth().onAuthStateChanged((user) => { ... });
  }, [firebase]);
}

这与Firebase在浏览器环境中使用并可以访问浏览器有关,这是Web SDK正常运行所必需的.

This works as Firebase is being used in a browser environment and has access to the browser, which is needed for the Web SDK to work.

它确实有缺点;在需要Firebase来显示内容的情况下,您的compo必须返回null,这意味着您在服务器上构建的HTML将不包含任何HTML,并且将通过客户端进行注入.不过,在大多数情况下,例如account页面,这很好.

It does have drawbacks; your compo have to return null in instances when you need Firebase to display content, which will mean your HTML build on the server will not contain any HTML, and it'll be injected via the client. In most cases though, such as an account page, this is fine.

如果您需要访问Cloud Firestore中的数据以显示页面内容,则最好使用Admin SDK来获取内容并将其添加到Gatsby构建过程中.这样,它将在构建期间在服务器上可用.

If you need access to data from say Cloud Firestore to display page content, you're best using the Admin SDK to fetch content and add it to GraphQL during Gatsby build. That way it will be available on the server during build time.

抱歉,这是华夫饼干还是不清楚!

Sorry if that was a waffle or not clear!

这篇关于如何在Gatsby中初始化Firebase?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆