Für Apps, in denen derzeit eine Firebase Web API mit Namespace verwendet wird, z. B. aus den compat
-Bibliotheken bis Version 8 oder niedriger, sollten Sie die Migration zur modularen API mithilfe der Anleitung in diesem Leitfaden in Betracht ziehen.
In dieser Anleitung wird davon ausgegangen, dass Sie mit der API mit Namensraum vertraut sind und einen Modul-Bundler wie Webpack oder Rollup für das Upgrade und die fortlaufende modulare App-Entwicklung verwenden.
Wir empfehlen dringend, in Ihrer Entwicklungsumgebung einen Modul-Bundler zu verwenden. Andernfalls können Sie die Hauptvorteile der modularen API in Bezug auf die reduzierte App-Größe nicht nutzen. Du benötigst npm oder yarn, um das SDK zu installieren.
Die Schritte zum Upgrade in dieser Anleitung beziehen sich auf eine fiktive Webanwendung, die die Authentication- und Cloud Firestore-SDKs verwendet. Wenn Sie die Beispiele durchgehen, können Sie die Konzepte und praktischen Schritte beherrschen, die für das Upgrade aller unterstützten Firebase Web SDKs erforderlich sind.
Namespaces für Bibliotheken (compat
)
Für das Firebase Web SDK sind zwei Arten von Bibliotheken verfügbar:
- Modular: Eine neue API-Oberfläche, die das Tree-Shaking (Entfernen von nicht verwendetem Code) vereinfacht, um Ihre Webanwendung so klein und schnell wie möglich zu machen.
- Mit Namensbereich (
compat
): Eine vertraute API-Oberfläche, die vollständig mit den früheren Versionen des SDKs kompatibel ist. So können Sie ein Upgrade durchführen, ohne den gesamten Firebase-Code auf einmal zu ändern. Compat-Bibliotheken bieten im Vergleich zu ihren Namespace-Äquivalenten kaum oder gar keine Vorteile in Bezug auf Größe oder Leistung.
In diesem Leitfaden wird davon ausgegangen, dass Sie die Compat-Bibliotheken nutzen, um das Upgrade zu vereinfachen. Mit diesen Bibliotheken können Sie weiterhin Code mit Namespace neben Code verwenden, der für die modulare API umgeschrieben wurde. So können Sie Ihre App beim Upgrade einfacher kompilieren und debuggen.
Bei Apps, die nur sehr wenig mit dem Firebase Web SDK interagieren, z. B. einer App, die nur einen einfachen Aufruf der Authentication APIs ausführt, kann es sinnvoll sein, älteren Code mit Namensraum ohne Verwendung der kompatiblen Bibliotheken zu überarbeiten. Wenn Sie eine solche App aktualisieren, können Sie der Anleitung in diesem Leitfaden für die modulare API folgen, ohne die Compat-Bibliotheken zu verwenden.
Informationen zum Upgrade-Prozess
Jeder Schritt des Upgrade-Prozesses ist so angelegt, dass Sie die Quelldatei für Ihre App fertig bearbeiten und dann ohne Unterbrechungen kompilieren und ausführen können. So aktualisieren Sie eine App:
- Fügen Sie Ihrer App die modularen und die kompatiblen Bibliotheken hinzu.
- Aktualisieren Sie die Importanweisungen in Ihrem Code auf „compat“.
- Refaktorieren Sie den Code für ein einzelnes Produkt (z. B. Authentication) im modularen Stil.
- Optional: Entfernen Sie an dieser Stelle die Authentication-Kompatibilitätsbibliothek und den Authentication-Kompatibilitätscode, um den Vorteil bei der App-Größe für Authentication zu nutzen, bevor Sie fortfahren.
- Erstellen Sie für jedes Produkt (z. B. Cloud Firestore, FCM usw.) Funktionen im modularen Stil, kompilieren Sie sie und testen Sie sie, bis alle Bereiche fertig sind.
- Aktualisieren Sie den Initialisierungscode auf den modularen Stil.
- Entfernen Sie alle verbleibenden Kompatibilitätsanweisungen und den Kompatibilitätscode aus Ihrer App.
Neueste Version des SDKs herunterladen
Lade zuerst die modularen und kompatiblen Bibliotheken mit npm herunter:
npm i firebase@11.1.0 # OR yarn add firebase@11.1.0
Importe auf „compat“ aktualisieren
Damit Ihr Code nach dem Aktualisieren der Abhängigkeiten weiterhin funktioniert, ändern Sie Ihre Importanweisungen so, dass die „compat“-Version jedes Imports verwendet wird. Beispiel:
Vorher: Version 8 oder älter
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
Nachher: compat
// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
Zum modularen Stil umstrukturieren
Während die APIs mit Namespace auf einem durch Punkte verknüpften Namespace- und Dienstmuster basieren, bedeutet der modulare Ansatz, dass Ihr Code hauptsächlich um Funktionen herum organisiert wird. In der modularen API geben das Paket firebase/app
und andere Pakete keinen umfassenden Export zurück, der alle Methoden aus dem Paket enthält. Stattdessen werden einzelne Funktionen exportiert.
In der modularen API werden Dienste als erstes Argument übergeben. Die Funktion verwendet dann die Details des Dienstes, um den Rest zu erledigen. Sehen wir uns an, wie das in zwei Beispielen funktioniert, in denen Aufrufe der Authentication- und Cloud Firestore-APIs umgeschrieben werden.
Beispiel 1: Refactoring einer Authentication-Funktion
Vorher: compat
Der Compat-Code ist mit dem Code mit Namespace identisch, aber die Importe haben sich geändert.
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
const auth = firebase.auth();
auth.onAuthStateChanged(user => {
// Check for user status
});
Nachher: modular
Die Funktion getAuth
verwendet firebaseApp
als ersten Parameter.
Die onAuthStateChanged
-Funktion wird nicht über die auth
-Instanz verkettet, wie es in der API mit Namespace der Fall wäre. Stattdessen ist es eine kostenlose Funktion, die auth
als ersten Parameter annimmt.
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
// Check for user status
});
Aktualisierung der Authentifizierungsmethode getRedirectResult
Die modulare API führt in getRedirectResult
eine funktionsgefährdende Änderung ein. Wenn kein Weiterleitungsvorgang aufgerufen wird, gibt die modulare API null
zurück, im Gegensatz zur API mit Namespace, die eine UserCredential
mit einem null
-Nutzer zurückgibt.
Vorher: compat
const result = await auth.getRedirectResult()
if (result.user === null && result.credential === null) {
return null;
}
return result;
Nachher: modular
const result = await getRedirectResult(auth);
// Provider of the access token could be Facebook, Github, etc.
if (result === null || provider.credentialFromResult(result) === null) {
return null;
}
return result;
Beispiel 2: Refactoring einer Cloud Firestore-Funktion
Vorher: compat
import "firebase/compat/firestore"
const db = firebase.firestore();
db.collection("cities").where("capital", "==", true)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
Nachher: modular
Die Funktion getFirestore
nimmt firebaseApp
als ersten Parameter an, der in einem früheren Beispiel von initializeApp
zurückgegeben wurde. Beachten Sie, dass sich der Code zum Erstellen einer Abfrage in der modularen API stark von der ursprünglichen API unterscheidet. Es gibt keine Verknüpfung und Methoden wie query
oder where
werden jetzt als kostenlose Funktionen bereitgestellt.
import { getFirestore, collection, query, where, getDocs } from "firebase/firestore";
const db = getFirestore(firebaseApp);
const q = query(collection(db, "cities"), where("capital", "==", true));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
Verweise auf Firestore aktualisieren DocumentSnapshot.exists
Die modulare API führt eine nicht abwärtskompatible Änderung ein, bei der das Attribut firestore.DocumentSnapshot.exists
in eine Methode geändert wurde. Die Funktionsweise ist im Wesentlichen dieselbe (Prüfen, ob ein Dokument vorhanden ist), aber Sie müssen Ihren Code so umstrukturieren, dass die neuere Methode verwendet wird, wie hier gezeigt:
Before:compat
if (snapshot.exists) {
console.log("the document exists");
}
Nachher: modular
if (snapshot.exists()) {
console.log("the document exists");
}
Beispiel 3: Kombination von Namespaces und modularem Codestil
Wenn Sie die kompatiblen Bibliotheken während des Upgrades verwenden, können Sie weiterhin Code mit Namensraum und Code verwenden, der für die modulare API umgeschrieben wurde. Das bedeutet, dass Sie vorhandenen Code mit Namensraum für Cloud Firestore beibehalten können, während Sie Authentication oder anderen Firebase SDK-Code in den modularen Stil umwandeln und Ihre App trotzdem mit beiden Codestilen kompilieren können. Dasselbe gilt für benannte und modulare API-Code innerhalb eines Produkts wie Cloud Firestore. Neue und alte Codestile können nebeneinander existieren, solange Sie die Compat-Pakete importieren:
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import { getDoc } from 'firebase/firestore'
const docRef = firebase.firestore().doc();
getDoc(docRef);
Denken Sie daran, dass Ihre App zwar kompiliert wird, Sie aber erst dann die Vorteile des modularen Codes in Bezug auf die App-Größe nutzen können, wenn Sie die Compat-Anweisungen und den Compat-Code vollständig aus Ihrer App entfernt haben.
Initialisierungscode aktualisieren
Aktualisieren Sie den Initialisierungscode Ihrer App, um die modulare Syntax zu verwenden. Es ist wichtig, diesen Code nach dem Refactoring des gesamten Codes in Ihrer App zu aktualisieren. Das liegt daran, dass firebase.initializeApp()
den globalen Status sowohl für die kompatiblen als auch für die modularen APIs initialisiert, während die modulare Funktion initializeApp()
nur den Status für die modulare API initialisiert.
Vorher: compat
import firebase from "firebase/compat/app"
firebase.initializeApp({ /* config */ });
Nachher: modular
import { initializeApp } from "firebase/app"
const firebaseApp = initializeApp({ /* config */ });
Compat-Code entfernen
Um die Vorteile der modularen API in Bezug auf die Größe zu nutzen, sollten Sie alle Aufrufe in den oben gezeigten modularen Stil konvertieren und alle import "firebase/compat/*
-Anweisungen aus Ihrem Code entfernen. Wenn Sie fertig sind, sollten keine Verweise mehr auf den globalen firebase.*
-Namespace oder anderen Code im API-Stil mit Namespace vorhanden sein.
Compat-Bibliothek über das Fenster verwenden
Die modulare API ist für die Verwendung mit Modulen und nicht mit dem window
-Objekt des Browsers optimiert. In früheren Versionen der Bibliothek konnten Firebase-Ressourcen über den Namespace window.firebase
geladen und verwaltet werden. Dies wird jedoch nicht empfohlen, da dadurch nicht verwendeter Code nicht entfernt werden kann.
Die kompatible Version des JavaScript SDK funktioniert jedoch mit der window
für Entwickler, die den modularen Upgradepfad nicht sofort starten möchten.
<script src="https://www.gstatic.com/firebasejs/11.1.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/11.1.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/11.1.0/firebase-auth-compat.js"></script>
<script>
const firebaseApp = firebase.initializeApp({ /* Firebase config */ });
const db = firebaseApp.firestore();
const auth = firebaseApp.auth();
</script>
Die Kompatibilitätsbibliothek verwendet modularen Code und stellt dieselbe API wie die netzwerkorientierte API bereit. Weitere Informationen finden Sie in der Referenz für die netzwerkorientierte API und in den netzwerkorientierten Code-Snippets. Diese Methode wird nicht für die langfristige Verwendung empfohlen, sondern als Ausgangspunkt für die Umstellung auf die vollständig modulare Bibliothek.
Vorteile und Einschränkungen des modularen SDK
Das vollständig modulare SDK bietet gegenüber früheren Versionen folgende Vorteile:
- Das modulare SDK ermöglicht eine deutlich geringere App-Größe. Es verwendet das moderne JavaScript-Modulformat und ermöglicht das „Tree Shaking“, bei dem nur die Artefakte importiert werden, die für Ihre App erforderlich sind. Je nach App kann das Tree-Shaking mit dem modularen SDK zu 80% weniger Kilobyten führen als bei einer vergleichbaren App, die mit der benannten API erstellt wurde.
- Das modulare SDK profitiert weiterhin von der kontinuierlichen Funktionsentwicklung, während dies bei der API mit Namespace nicht der Fall ist.