Aplikacje, które obecnie korzystają z dowolnego interfejsu Firebase Web API w dowolnej przestrzeni nazw (z bibliotek compat
w wersji 8 lub starszej), powinny rozważyć migrację do interfejsu modularnego API zgodnie z instrukcjami podanymi w tym przewodniku.
W tym przewodniku zakładamy, że znasz interfejs API z nazwą przestrzeni nazw i że do uaktualniania oraz dalszego tworzenia modułowej aplikacji będziesz używać usługi tworzenia pakietów modułów, takiej jak webpack lub Rollup.
Zdecydowanie zalecamy korzystanie z pakowacza modułów w środowisku programistycznym. Jeśli nie użyjesz żadnego z nich, nie będziesz mieć możliwości skorzystania z głównych zalet interfejsu API w zakresie zmniejszenia rozmiaru aplikacji. Aby zainstalować pakiet SDK, musisz użyć npm lub yarn.
Kroki uaktualniania w tym przewodniku będą oparte na przykładowej aplikacji internetowej, która korzysta z pakietów SDK Authentication i Cloud Firestore. Dzięki przykładom możesz poznać zagadnienia i konkretne kroki wymagane do uaktualnienia wszystkich obsługiwanych pakietów SDK Firebase Web.
Informacje o bibliotekach w przestrzeni nazw (compat
)
W przypadku pakietu Firebase Web SDK dostępne są 2 typy bibliotek:
- Modularność – nowa wersja interfejsu API, która ułatwia usuwanie zbędącego kodu (czyli jego usuwanie z drzewa), aby Twoja aplikacja internetowa była jak najmniejsza i jak najszybsza.
- W przestrzeni nazw (
compat
) – znajoma interfejs API, który jest w pełni zgodny z wcześniejszymi wersjami pakietu SDK. Umożliwia to uaktualnienie bez jednoczesnej zmiany całego kodu Firebase. Biblioteki zgodności mają niewielką przewagę nad bibliotekami z przestrzenią nazw pod względem rozmiaru i wydajności.
W tym przewodniku zakładamy, że użyjesz bibliotek kompatybilnych, aby ułatwić sobie przekształcenie. Te biblioteki umożliwiają dalsze używanie kodu z przestrzenią nazw obok kodu zmodyfikowanego pod kątem interfejsu API w wersji modułowej. Oznacza to, że podczas procesu aktualizacji możesz łatwiej skompilować i przeprowadzić debugowanie aplikacji.
W przypadku aplikacji, które korzystają z pakietu SDK Firebase Web w niewielkim stopniu (np. aplikacji, która wykonuje tylko proste wywołanie interfejsów API Authentication), warto zrefaktoryzować starszy kod z nazwą przestrzeni bez używania bibliotek zgodnych z wersją. Jeśli aktualizujesz taką aplikację, możesz postępować zgodnie z instrukcjami w tym przewodniku dotyczącymi „Modułowego interfejsu API” bez używania bibliotek zgodności.
Proces uaktualniania
Każdy krok procesu uaktualniania jest ograniczony, aby umożliwić Ci dokończenie edycji kodu źródłowego aplikacji, a następnie jej skompilowanie i uruchomienie bez żadnych problemów. Oto, co musisz zrobić, aby zaktualizować aplikację:
- Dodaj do aplikacji modułowe biblioteki i biblioteki zgodności.
- Zaktualizuj instrukcje importowania w kodzie, aby używały pakietu compat.
- Przerzuć kod pojedynczego produktu (np. Authentication) do stylu modułowego.
- Opcjonalnie: na tym etapie usuń bibliotekę zgodności Authentication i kod zgodności dla Authentication, aby uzyskać korzyści związane z rozmiarem aplikacji dla Authentication, zanim przejdziesz dalej.
- Przepisz funkcje każdego produktu (np. Cloud Firestore, FCM itp.) w stylu modułowym, kompilując i testując, aż wszystkie obszary zostaną ukończone.
- Zaktualizuj kod inicjowania do stylu modułowego.
- Usuń ze swojej aplikacji wszystkie pozostałe oświadczenia i kod zgodności.
Pobieranie najnowszej wersji pakietu SDK
Aby rozpocząć, pobierz biblioteki modułowe i biblioteki zgodne za pomocą npm:
npm i firebase@11.1.0 # OR yarn add firebase@11.1.0
Aktualizowanie importów do wersji zgodnej
Aby kod działał prawidłowo po zaktualizowaniu zależności, zmień instrukcje importu, aby używać wersji „compat” każdego importu. Przykład:
Wcześniej: wersja 8 lub starsza
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
Po: compat
// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
Przerzuć się na styl modułowy
Chociaż interfejsy API z przestrzenią nazw są oparte na wzorze przestrzeni nazw i usług połączonych kropką, podejście modułowe oznacza, że Twój kod będzie zorganizowany głównie wokół funkcji. W modularnym interfejsie API pakiet firebase/app
i inne pakiety nie zwracają kompleksowego eksportu zawierającego wszystkie metody z pakietu. Zamiast tego pakiety eksportują poszczególne funkcje.
W interfejsie API w wersji modułowej usługi są przekazywane jako pierwszy argument, a funkcja wykorzystuje szczegóły usługi do wykonania reszty czynności. Przyjrzyjmy się, jak to działa na przykładzie dwóch przykładów, które refaktoryzują wywołania interfejsów API Authentication i Cloud Firestore.
Przykład 1. Refaktoryzacja funkcji Authentication
Wcześniej: zgodność
Kod zgodności jest identyczny z kodem w przestrzeni nazw, ale importy zostały zmienione.
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
const auth = firebase.auth();
auth.onAuthStateChanged(user => {
// Check for user status
});
Po: modułowe
Funkcja getAuth
przyjmuje jako pierwszy parametr firebaseApp
.
Funkcja onAuthStateChanged
nie jest powiązana z instancją auth
, jak ma to miejsce w przypadku interfejsu API z nazwą przestrzeni nazw. Zamiast tego jest to wolna funkcja, która jako pierwszy parametr przyjmuje wartość auth
.
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
// Check for user status
});
Aktualizacja obsługi metody uwierzytelniania getRedirectResult
Interfejs API w wersji modułowej wprowadza zmiany w interfejsie getRedirectResult
. Gdy nie wywołano żadnej operacji przekierowania, interfejs modularny zwraca null
, a nie interfejs z przestrzenią nazw, który zwraca UserCredential
z użytkownikiem null
.
Wcześniej: zgodność
const result = await auth.getRedirectResult()
if (result.user === null && result.credential === null) {
return null;
}
return result;
Po: modułowe
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;
Przykład 2. Refaktoryzacja funkcji Cloud Firestore
Wcześniej: zgodność
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);
});
Po: modułowe
Funkcja getFirestore
przyjmuje jako pierwszy parametr firebaseApp
, który został zwrócony przez funkcję initializeApp
w poprzednim przykładzie. Zwróć uwagę, że kod służący do tworzenia zapytania jest w modularnym interfejsie API bardzo różny. Nie ma w nim łańcuchów, a metody takie jak query
czy where
są teraz dostępne jako funkcje wolne.
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());
});
Aktualizowanie odwołań do Firestore DocumentSnapshot.exists
Modułowe API wprowadza istotną zmianę, w której właściwość firestore.DocumentSnapshot.exists
została zastąpiona przez metodę. Funkcjonalność jest zasadniczo taka sama (sprawdzanie, czy dokument istnieje), ale musisz przerobić kod, aby używać nowszej metody:
Przed:compat
if (snapshot.exists) {
console.log("the document exists");
}
Po: modułowe
if (snapshot.exists()) {
console.log("the document exists");
}
Przykład 3. Łączenie stylów kodu z przestrzenią nazw i modułowym kodem
Korzystanie z bibliotek zgodnych podczas uaktualniania umożliwia dalsze używanie kodu z przestrzenią nazw obok kodu zrefaktoryzowanego pod kątem modułowego interfejsu API. Oznacza to, że możesz zachować istniejący kod w przestrzeni nazw dla pakietu Cloud Firestore, a zarazem przeprowadzić refaktoryzację kodu Authentication lub innego kodu pakietu SDK Firebase do stylu modułowego. Nadal możesz kompilować aplikację z użyciem obu tych stylów. To samo dotyczy kodu interfejsu API z przestrzenią nazw i interfejsu API w formie modułów w ramach usługi, takiej jak Cloud Firestore. Nowe i stare style kodu mogą współistnieć, o ile importujesz pakiety zgodne:
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import { getDoc } from 'firebase/firestore'
const docRef = firebase.firestore().doc();
getDoc(docRef);
Pamiętaj, że chociaż kompilacja aplikacji się powiedzie, nie uzyskasz korzyści wynikających z mniejszego rozmiaru kodu modułowego, dopóki nie usuniesz z aplikacji instrukcji kompatybilności i kodu.
Aktualizowanie kodu inicjowania
Zaktualizuj kod inicjalizacji aplikacji, aby używać składni modułowej. Należy zaktualizować ten kod po zakończeniu refaktoryzacji całego kodu w aplikacji. Dzieje się tak, ponieważ funkcja firebase.initializeApp()
inicjuje stan globalny zarówno dla interfejsów API kompatybilnych, jak i modularnych, a funkcja modularna initializeApp()
inicjuje tylko stan dla interfejsu modularnego.
Wcześniej: zgodność
import firebase from "firebase/compat/app"
firebase.initializeApp({ /* config */ });
Po: modułowe
import { initializeApp } from "firebase/app"
const firebaseApp = initializeApp({ /* config */ });
Usuwanie kodu zgodności
Aby uzyskać korzyści wynikające z interfejsu API w wersji modułowej, musisz przekształcić wszystkie wywołania w modułowy styl pokazany powyżej i usunąć z kodu wszystkie instrukcje import "firebase/compat/*
. Po zakończeniu nie powinno być już żadnych odwołań do globalnej przestrzeni nazw firebase.*
ani innych fragmentów kodu w stylu interfejsu API z przestrzenią nazw.
Korzystanie z biblioteki kompatybilności w oknie
Interfejs modularny API jest zoptymalizowany pod kątem pracy z modułami, a nie obiektem window
przeglądarki. W poprzednich wersjach biblioteki można było wczytywać i zarządzać Firebase za pomocą przestrzeni nazw window.firebase
. Nie zalecamy tego w przyszłości, ponieważ nie pozwala na wyeliminowanie nieużywanego kodu.
Wersja zgodna pakietu SDK JavaScript działa jednak z window
w przypadku deweloperów, którzy nie chcą od razu przechodzić na modułową ścieżkę aktualizacji.
<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>
Biblioteka zgodności używa modułowego kodu i zapewnia ten sam interfejs API co interfejs z przestrzenią nazw. Oznacza to, że szczegółowe informacje znajdziesz w dokumentacji interfejsu API z przestrzenią nazw i fragmentach kodu z przestrzenią nazw. Ta metoda nie jest zalecana do długotrwałego stosowania, ale może być użyta jako pierwszy krok w przechodzeniu na całkowicie modułową bibliotekę.
Zalety i ograniczenia modułowego pakietu SDK
W pełni modułowy pakiet SDK ma te zalety w porównaniu z wcześniejszymi wersjami:
- Modułowy pakiet SDK pozwala znacznie zmniejszyć rozmiar aplikacji. Jest ono oparte na nowoczesnym formacie modułu JavaScript, który umożliwia „tree shaking” (czyli usuwanie z drzewa) i importowanie tylko tych artefaktów, których potrzebuje aplikacja. W zależności od aplikacji, zastosowanie metody tree-shaking w ramach modułowego pakietu SDK może spowodować zmniejszenie rozmiaru aplikacji o 80% w porównaniu z porównywalną aplikacją utworzoną przy użyciu interfejsu API z nazwą przestrzeni nazw.
- Modułowy pakiet SDK będzie nadal korzystać z rozwijanych funkcji, podczas gdy interfejs API z przestrzenią nazw nie będzie.