Используйте Firebase в динамических веб-приложениях с SSR (серверный рендеринг), используйте Firebase в динамических веб-приложениях с SSR (серверный рендеринг)

Если вы работали с Firebase JS SDK или другими клиентскими SDK Firebase, вы, вероятно, знакомы с интерфейсом FirebaseApp и тем, как использовать его для настройки экземпляров приложений. Для упрощения аналогичных операций на стороне сервера Firebase предоставляет FirebaseServerApp .

FirebaseServerApp — это вариант FirebaseApp для использования в средах серверного рендеринга (SSR). Он включает в себя инструменты для продолжения сеансов Firebase, охватывающих клиентский (CSR) и серверный рендеринг. Эти инструменты и стратегии помогут улучшить динамические веб-приложения, созданные с помощью Firebase и развёрнутые в средах Google, таких как Firebase App Hosting .

Используйте FirebaseServerApp для:

  • Выполнять серверный код в контексте пользователя , в отличие от Firebase Admin SDK, который имеет полные права администратора.
  • Включить использование App Check в средах SSR.
  • Продолжить сеанс аутентификации Firebase, созданный в клиенте.

Жизненный цикл FirebaseServerApp

Фреймворки серверного рендеринга (SSR) и другие среды выполнения, не работающие в браузере, такие как облачные рабочие процессы, оптимизируют время инициализации, повторно используя ресурсы в нескольких выполнениях. FirebaseServerApp разработан для работы в таких средах с помощью механизма подсчёта ссылок. Если приложение вызывает initializeServerApp с теми же параметрами, что и предыдущий initializeServerApp , оно получает тот же экземпляр FirebaseServerApp , который уже был инициализирован. Это сокращает ненужные накладные расходы на инициализацию и выделение памяти. При вызове deleteApp для экземпляра FirebaseServerApp счётчик ссылок уменьшается, и экземпляр освобождается после того, как он достигнет нуля.

Очистка экземпляров FirebaseServerApp

Иногда бывает сложно определить, когда следует вызывать deleteApp для экземпляра FirebaseServerApp , особенно если вы параллельно выполняете множество асинхронных операций. Поле releaseOnDeref объекта FirebaseServerAppSettings упрощает этот процесс. Если назначить releaseOnDeref ссылку на объект, срок действия которого совпадает с областью действия запроса (например, объект заголовков запроса SSR), FirebaseServerApp уменьшит количество ссылок, когда фреймворк вернет объект заголовка. Это автоматически очистит ваш экземпляр FirebaseServerApp .

Вот пример использования releaseOnDeref :

/// Next.js
import { headers } from 'next/headers'
import { FirebaseServerAppSettings, initializeServerApp} from "@firebase/app";

export default async function Page() {
  const headersObj = await headers();
  appSettings.releaseOnDeref = headersObj;
  let appSettings: FirebaseServerAppSettings = {};
  const serverApp = initializeServerApp(firebaseConfig, appSettings);
  ...
}

Возобновить аутентифицированные сеансы, созданные на клиенте

При инициализации экземпляра FirebaseServerApp с токеном Auth ID он обеспечивает соединение сеансов аутентифицированных пользователей между средами клиентского рендеринга (CSR) и серверного рендеринга (SSR). Экземпляры Firebase Auth SDK, инициализированные объектом FirebaseServerApp , содержащим токен Auth ID, будут пытаться выполнить вход пользователя при инициализации, без необходимости вызова каких-либо методов входа со стороны приложения.

Предоставление токена Auth ID позволяет приложениям использовать любые методы входа Auth на клиенте, гарантируя продолжение сеанса на стороне сервера, даже для тех методов входа, которые требуют взаимодействия с пользователем. Кроме того, это позволяет перенести на сервер ресурсоёмкие операции, такие как запросы к Firestore с аутентификацией, что должно повысить производительность рендеринга вашего приложения.

/// Next.js
import { initializeServerApp } from "firebase/app";
import { getAuth } from "firebase/auth";

// Replace the following with your app's
// Firebase project configuration
const firebaseConfig = {
  // ...
};

const firebaseServerAppSettings = {
  authIdToken: token  // See "Pass client tokens to the server side
                      // rendering phase" for an example on how transmit
                      // the token from the client and the server.
}

const serverApp =
  initializeServerApp(firebaseConfig,
                      firebaseServerAppSettings);
const serverAuth = getAuth(serverApp);

// FirebaseServerApp and Auth will now attempt
// to sign in the current user based on provided
// authIdToken.

Используйте проверку приложений в средах SSR

Для обеспечения проверки приложений используется экземпляр App Check SDK, который Firebase SDK использует для внутреннего вызова getToken . Полученный токен затем включается в запросы ко всем службам Firebase, что позволяет бэкенду проверять приложение.

Однако, поскольку для App Check SDK необходим браузер для доступа к определенным эвристикам проверки приложений, его невозможно инициализировать в серверных средах.

FirebaseServerApp предоставляет альтернативу. Если во время инициализации FirebaseServerApp предоставляется токен App Check, сгенерированный клиентом, он будет использоваться SDK продуктов Firebase при вызове служб Firebase, что устраняет необходимость в экземпляре SDK App Check.

/// Next.js
import { initializeServerApp } from "firebase/app";

// Replace the following with your app's
// Firebase project configuration
const firebaseConfig = {
  // ...
};

const firebaseServerAppSettings = {
  appCheckToken: token // See "Pass client tokens to the server side
                       // rendering phase" for an example on how transmit
                       // the token from the client and the server.
}

const serverApp =
  initializeServerApp(firebaseConfig,
                      firebaseServerAppSettings);

// The App Check token will now be appended to all Firebase service requests.

Передача клиентских токенов на этап рендеринга на стороне сервера

Для передачи аутентифицированных токенов Auth ID (и токенов App Check) от клиента к этапу рендеринга на стороне сервера (SSR) используется сервис-воркер. Этот подход включает перехват запросов на выборку, запускающих SSR, и добавление токенов к заголовкам запросов.

Пример реализации сервис-воркера Firebase Auth см. в разделе «Управление сеансами с помощью сервис-воркеров» . Также см. раздел «Изменения на стороне сервера» для кода, демонстрирующего, как извлекать эти токены из заголовков для использования при инициализации FirebaseServerApp .