Поскольку Gatsby создает страницы в серверной среде, вы не можете получить доступ к Firebase во время сборки Gatsby. Вызовы Firebase (с использованием Web SDK) должны выполняться, когда пользователь находится в среде браузера / клиента.
Одним из решений этой проблемы является создание такой функции:
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;
}
Этот файл возвращает функцию, которая возвращает экземпляр Firebase, если пользователю доступен глобальный window
(например, в браузере). Он также кэширует экземпляр Firebase, чтобы гарантировать, что он не может быть повторно инициализирован повторно (в случае, если пользователь изменяет страницу на вашем веб-сайте).
В ваших компонентах вы можете теперь сделать что-то похожее на следующее:
import getFirebase from './firebase';
function MyApp() {
const firebase = getFirebase();
}
Поскольку Gatsby будет пытаться встроить эту страницу в HTML во время gatsby build
, констант firebase
вернет ноль, что является правильным, поскольку Firebase Web SDK не может инициализироваться в серверной среде. Однако, чтобы использовать Firebase на вашем сайте, вам нужно подождать, пока Firebase станет доступным (чтобы пользователь загрузил ваш сайт), чтобы мы могли использовать ловушку Reacts useEffect
:
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.
У него есть недостатки;ваша компоновка должна возвращать null
в тех случаях, когда вам нужен Firebase для отображения контента, что будет означать, что ваша HTML-сборка на сервере не будет содержать HTML, и она будет внедрена через клиента. Однако в большинстве случаев, например, на странице account
, это нормально.
Если вам нужен доступ к данным, например, из Cloud Firestore, для отображения содержимого страницы, лучше всего использовать Admin SDK для получения содержимого идобавьте его в GraphQL во время сборки Gatsby. Таким образом, он будет доступен на сервере во время сборки.
Извините, если это была вафля или неясно!