Jeśli masz doświadczenie z pakietem Firebase JS SDK lub innymi pakietami Firebase Client SDK, prawdopodobnie znasz interfejs FirebaseApp i wiesz, jak go używać do konfigurowania instancji aplikacji. Aby ułatwić podobne operacje po stronie serwera, Firebase udostępnia FirebaseServerApp.
FirebaseServerApp to wariant FirebaseApp do użytku w środowiskach renderowania po stronie serwera (SSR). Zawiera narzędzia do kontynuowania sesji Firebase, które obejmują renderowanie po stronie klienta (CSR) i renderowanie po stronie serwera. Te
narzędzia i strategie mogą pomóc w ulepszaniu dynamicznych aplikacji internetowych utworzonych za pomocą Firebase i
wdrożonych w środowiskach Google, takich jak
Firebase App Hosting.
Użyj FirebaseServerApp, aby:
- wykonywać kod po stronie serwera w kontekście użytkownika , w przeciwieństwie do pakietu Firebase Admin SDK, który ma pełne uprawnienia administracyjne;
- umożliwić korzystanie ze Sprawdzania aplikacji w środowiskach SSR;
- kontynuować sesję Firebase Auth utworzoną po stronie klienta.
Cykl życia FirebaseServerApp
Frameworki renderowania po stronie serwera (SSR) i inne środowiska wykonawcze inne niż przeglądarka, takie jak Cloud Workers, optymalizują czas inicjowania przez ponowne wykorzystywanie zasobów w wielu wykonaniach. FirebaseServerApp jest zaprojektowany tak, aby obsługiwać te środowiska za pomocą mechanizmu zliczania odwołań. Jeśli aplikacja wywoła initializeServerApp z tymi samymi parametrami co poprzednie initializeServerApp, otrzyma tę samą instancję FirebaseServerApp, która została już zainicjowana. Pozwala to ograniczyć niepotrzebne obciążenie związane z inicjowaniem i alokacją pamięci. Gdy w instancji FirebaseServerApp zostanie wywołana funkcja deleteApp, zmniejszy się liczba odwołań, a instancja zostanie zwolniona, gdy liczba odwołań osiągnie zero.
Czyszczenie instancji FirebaseServerApp
Trudno jest określić, kiedy należy wywołać deleteApp w instancji FirebaseServerApp, zwłaszcza jeśli równolegle wykonujesz wiele operacji asynchronicznych. Ułatwia to pole releaseOnDeref w FirebaseServerAppSettings. Jeśli przypiszesz releaseOnDeref odwołanie do obiektu o okresie istnienia zakresu żądania (np. obiektu nagłówków żądania SSR), FirebaseServerApp zmniejszy liczbę odwołań, gdy framework odzyska obiekt nagłówka. Spowoduje to automatyczne wyczyszczenie instancji FirebaseServerApp.
Oto przykład użycia releaseOnDeref:
/// Next.js
import { headers } from 'next/headers'
import { FirebaseServerAppSettings, initializeServerApp} from "firebase/app";
export default async function Page() {
const headersObj = await headers();
let appSettings: FirebaseServerAppSettings = {};
appSettings.releaseOnDeref = headersObj;
const serverApp = initializeServerApp(firebaseConfig, appSettings);
...
}
Wznawianie sesji uwierzytelnionych utworzonych po stronie klienta
Gdy instancja FirebaseServerApp zostanie zainicjowana za pomocą tokena identyfikatora Auth, umożliwi to połączenie sesji uwierzytelnionych użytkowników między środowiskami renderowania po stronie klienta (CSR) i renderowania po stronie serwera (SSR). Instancje pakietu Firebase Auth SDK zainicjowane za pomocą obiektu FirebaseServerApp zawierającego token identyfikatora Auth będą próbować zalogować użytkownika podczas inicjowania bez konieczności wywoływania przez aplikację jakichkolwiek metod logowania.
Podanie tokena identyfikatora Auth umożliwia aplikacjom korzystanie z dowolnej metody logowania Auth po stronie klienta, co zapewnia kontynuowanie sesji po stronie serwera, nawet w przypadku metod logowania wymagających interakcji z użytkownikiem. Ponadto umożliwia to przeniesienie intensywnych operacji na serwer, takich jak uwierzytelnione zapytania Firestore, co powinno poprawić wydajność renderowania aplikacji.
/// 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.
Używanie Sprawdzania aplikacji w środowiskach SSR
Wymuszanie Sprawdzania aplikacji opiera się na instancji pakietu App Check SDK, której pakiety Firebase SDK używają do wewnętrznego wywoływania getToken. Wynikowy token jest następnie dołączany do żądań kierowanych do wszystkich usług Firebase, co umożliwia backendowi weryfikację aplikacji.
Jednak pakiet SDK Sprawdzania aplikacji potrzebuje przeglądarki, aby uzyskać dostęp do określonych heurystyk weryfikacji aplikacji, dlatego nie można go zainicjować w środowiskach serwerowych.
FirebaseServerApp zapewnia alternatywę. Jeśli podczas inicjowania FirebaseServerApp zostanie podany token Sprawdzania aplikacji wygenerowany przez klienta, będzie on używany przez pakiety Firebase SDK podczas wywoływania usług Firebase, co eliminuje potrzebę używania instancji pakietu App Check SDK.
/// 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.
Przekazywanie tokenów klienta do fazy renderowania po stronie serwera
Aby przesyłać uwierzytelnione tokeny identyfikatora Uwierzytelniania (i tokeny Sprawdzania aplikacji) z klienta do fazy renderowania po stronie serwera (SSR), użyj skryptu service worker. To podejście polega na przechwytywaniu żądań pobierania, które wywołują SSR, i dołączaniu tokenów do nagłówków żądań.
Implementację referencyjną skryptu service worker Firebase Auth znajdziesz w artykule Zarządzanie sesjami za pomocą skryptów service worker. Zobacz też Zmiany po stronie serwera aby dowiedzieć się, jak analizować te tokeny z nagłówków na potrzeby inicjowania FirebaseServerApp.
Używanie Firestore w środowiskach SSR
Podczas tworzenia aplikacji internetowych z renderowaniem po stronie serwera (SSR) często trzeba udostępniać dane między serwerem a klientem, aby zoptymalizować wydajność i wygodę użytkowników. Pakiet Firestore SDK udostępnia narzędzia do serializacji, które umożliwiają przechwytywanie zrzutów i określonych typów danych na serwerze oraz przekazywanie ich bezpośrednio do komponentów po stronie klienta. Ten proces eliminuje zbędne pobieranie danych, umożliwiając klientowi uzupełnianie stanu za pomocą danych pobranych wstępnie podczas fazy SSR. Dodatkowo możesz przejść z tych serializowanych stanów do detektorów czasu rzeczywistego, co zapewni synchronizację aplikacji z bazą danych.
W tej sekcji opisujemy, jak ponownie używać danych pobranych podczas fazy renderowania po stronie serwera (SSR) w komponentach po stronie klienta.
Serializowanie typów danych
Niektóre typy danych Firestore udostępniają metodę toJSON, która umożliwia konwertowanie danych na format serializowalny. Obejmują one instancje obiektów takich jak Bytes, GeoPoint, Timestamp i VectorValue.
Gdy dane są w formacie JSON, możesz je przekazywać z serwera do klienta za pomocą standardowych mechanizmów platformy lub jako parametry komponentów, które obejmują podział. Przykład:
import {
Bytes
} from 'firebase/firestore';
const BYTES_DATA = new Uint8Array([0, 1, 2, 3, 4, 5]);
const bytes = Bytes.fromUint8Array(BYTES_DATA);
const bytesJSON = bytes.toJSON();
Deserializowanie typów danych
Typy danych Firestore zawierają metodę statyczną fromJSON, która umożliwia konwertowanie serializowanych danych na typ danych Firestore, który można obsługiwać.
Na przykład poniższy kod deserializuje typ danych Bytes:
import {
Bytes
} from 'firebase/firestore';
// Assuming the same `bytesJSON` variable from the previous example.
const deserializedBytes = Bytes.fromJSON(bytesJSON);
Serializowanie i deserializowanie zrzutów Firestore
Podobnie jak w przypadku typów danych Firestore, możesz serializować instancje DocumentSnapshot i QuerySnapshot za pomocą toJSON. Aby je deserializować, musisz jednak użyć funkcji samodzielnych documentSnapshotFromJSON i querySnapshotFromJSON zamiast metody statycznej fromJSON.
Na przykład wyniki querySnapshot operacji query można
serializować za pomocą metody toJSON:
import {
collection,
getDocs,
query,
querySnapshotFromJSON
} from 'firebase/firestore';
// Assuming a configured instance of Firestore in the variable `firestore`.
const queryRef = query(collection(firestore, QUERY_PATH));
const querySnapshot = await getDocs(queryRef);
const querySnapshotJson = querySnapshot.toJSON();
Następnie te dane można deserializować:
import {
querySnapshotFromJSON
} from 'firebase/firestore';
// deserializedSnapshot is an object of type QuerySnapshot:
const deserializedSnapshot =
querySnapshotFromJSON(firestore, querySnapshotJson);
Detektory z serializowanymi zrzutami
Chociaż dane pobrane podczas fazy SSR są przydatne do początkowego renderowania CSR, może być konieczne monitorowanie usługi Firestore pod kątem aktualizacji tych informacji w czasie rzeczywistym.
Jeśli Twoja aplikacja wymaga tych aktualizacji w czasie rzeczywistym, możesz użyć funkcji onSnapshotResume
, aby zainicjować SnapshotListener Firestore za pomocą serializowanych danych Snapshot. Przykład:
const observer = {
next: (qs) => {
console.log("onSnapshot invoked: ", qs.data());
},
error: (e) => {
console.log("error callback invoked: ", e.toString());
}
};
const unsubscribe = onSnapshotResume(firestore, querySnapshotJson, observer);