Usar o Firebase em apps da Web dinâmicos com renderização do lado do servidor (SSR, na sigla em inglês)

Se você já trabalhou com o SDK do Firebase para JS ou outros SDKs de cliente do Firebase, provavelmente já conhece a interface do FirebaseApp e como usá-la para configurar instâncias de apps. Para facilitar operações semelhantes no lado do servidor, o Firebase oferece FirebaseServerApp.

FirebaseServerApp é uma variante do FirebaseApp para uso em ambientes de renderização do lado do servidor (SSR). Ele inclui ferramentas para continuar sessões do Firebase que abrangem a divisão entre a renderização do lado do cliente (CSR) e do lado do servidor. Essas ferramentas e estratégias podem ajudar a melhorar apps da Web dinâmicos criados com o Firebase e implantados em ambientes do Google, como o Firebase App Hosting.

Use o FirebaseServerApp para:

  • Executar código do lado do servidor no contexto do usuário, em contraste com o SDK Admin do Firebase, que tem direitos de administração completos.
  • Ative o uso do App Check em ambientes de SSR.
  • Continue uma sessão do Firebase Auth criada no cliente.

Ciclo de vida do FirebaseServerApp

Os frameworks de renderização do lado do servidor (SSR) e outros ambientes de execução que não são do navegador, como usuários da nuvem, otimizam o tempo de inicialização reutilizando recursos em várias execuções. O FirebaseServerApp foi projetado para acomodar esses ambientes usando um mecanismo de contagem de referência. Se um app invocar initializeServerApp com os mesmos parâmetros de um initializeServerApp anterior, ele vai receber a mesma instância FirebaseServerApp que já foi inicializada. Isso reduz o overhead desnecessário de inicialização e as alocações de memória. Quando deleteApp é invocado em uma instância FirebaseServerApp, ele reduz a contagem de referência, e a instância é liberada depois que a contagem de referência chega a zero.

Como limpar instâncias de FirebaseServerApp

Pode ser difícil saber quando chamar deleteApp em uma instância FirebaseServerApp, principalmente se você estiver executando muitas operações assíncronas em paralelo. O campo releaseOnDeref do FirebaseServerAppSettings ajuda a simplificar isso. Se você atribuir releaseOnDeref uma referência a um objeto com a duração do escopo da solicitação (por exemplo, o objeto de cabeçalhos da solicitação SSR), o FirebaseServerApp vai reduzir a contagem de referência quando o framework recuperar o objeto de cabeçalho. Isso limpa automaticamente sua instância FirebaseServerApp.

Confira um exemplo de uso de 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);
  ...
}

Retomar sessões autenticadas criadas no cliente

Quando uma instância de FirebaseServerApp é inicializada com um token de ID de autenticação, ela permite a ponte de sessões de usuários autenticados entre os ambientes de renderização do lado do cliente (CSR) e do lado do servidor (SSR). Instâncias do SDK do Firebase Auth inicializadas com um objeto FirebaseServerApp contendo um token de ID de autenticação vão tentar fazer login do usuário na inicialização sem a necessidade de o aplicativo invocar métodos de login.

Fornecer um token de ID de autenticação permite que os apps usem qualquer um dos métodos de login do Auth no cliente, garantindo que a sessão continue no lado do servidor, mesmo para os métodos de login que exigem interação do usuário. Além disso, ele permite o descarregamento de operações intensivas para o servidor, como consultas autenticadas do FireStore, o que deve melhorar o desempenho de renderização do app.

/// 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.

Usar o App Check em ambientes de SSR

A aplicação do App Check depende de uma instância do SDK do App Check que os SDKs do Firebase usam para chamar getToken internamente. O token resultante é incluído nas solicitações a todos os serviços do Firebase, permitindo que o back-end valide o app.

No entanto, como o SDK do App Check precisa de um navegador para acessar heurísticas específicas para a validação do app, ele não pode ser inicializado em ambientes de servidor.

FirebaseServerApp oferece uma alternativa. Se um token do App Check gerado pelo cliente for fornecido durante a inicialização do FirebaseServerApp, ele será usado pelos SDKs do produto do Firebase ao invocar os serviços do Firebase, eliminando a necessidade de uma instância do SDK do 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.

Transmitir tokens do cliente para a fase de renderização no lado do servidor

Para transmitir tokens de ID de autenticação (e tokens do App Check) autenticados do cliente para a fase de renderização do lado do servidor (SSR, na sigla em inglês), use um service worker. Essa abordagem consiste em interceptar solicitações de busca que acionam o SSR e anexar os tokens aos cabeçalhos de solicitação.

Consulte Gerenciamento de sessão com service workers para conferir uma implementação de referência de um service worker do Firebase Auth. Consulte também Mudanças do lado do servidor para conferir um código que demonstra como analisar esses tokens dos cabeçalhos para uso na inicialização de FirebaseServerApp.