Aplikacje korzystające z dowolnego interfejsu Firebase Web API z przestrzenią nazw z compat
bibliotekcompat
w wersji 8 lub starszej powinny rozważyć migrację do modułowego interfejsu API zgodnie z instrukcjami w tym przewodniku.
W tym przewodniku zakładamy, że znasz interfejs API z przestrzenią nazw i będziesz korzystać z usługi tworzenia pakietów modułów, takiej jak webpack lub Rollup, aby przeprowadzić aktualizację i kontynuować modułowe tworzenie aplikacji.
Zdecydowanie zalecamy używanie narzędzia do łączenia modułów w środowisku programistycznym. Jeśli nie używasz żadnego z nich, nie będziesz mieć możliwości korzystania z głównych zalet modułowego interfejsu API, czyli mniejszego rozmiaru aplikacji. Do zainstalowania pakietu SDK potrzebujesz npm lub yarn.
Instrukcje uaktualniania w tym przewodniku będą oparte na fikcyjnej aplikacji internetowej, która korzysta z pakietów SDK Authentication i Cloud Firestore. Dzięki tym przykładom opanujesz koncepcje i praktyczne kroki wymagane do uaktualnienia wszystkich obsługiwanych pakietów SDK Firebase do internetu.
Informacje o bibliotekach z przestrzenią nazw (compat
)
W przypadku pakietu Firebase Web SDK dostępne są 2 rodzaje bibliotek:
- Modularny – nowy interfejs API zaprojektowany tak, aby ułatwiać usuwanie nieużywanego kodu (tree-shaking), dzięki czemu aplikacja internetowa będzie jak najmniejsza i najszybsza.
- Z przestrzenią nazw (
compat
) – znany interfejs API, który jest w pełni zgodny z wcześniejszymi wersjami pakietu SDK, co umożliwia aktualizację bez konieczności jednoczesnej zmiany całego kodu Firebase. Biblioteki zgodności nie mają żadnych lub prawie żadnych zalet pod względem rozmiaru czy wydajności w porównaniu z ich odpowiednikami w przestrzeni nazw.
W tym przewodniku zakładamy, że do ułatwienia procesu przekształcenia użyjesz bibliotek zgodności. Te biblioteki umożliwiają dalsze korzystanie z kodu z przestrzenią nazw obok kodu przekształconego na potrzeby modułowego interfejsu API. Oznacza to, że w trakcie procesu uaktualniania możesz łatwiej kompilować i debugować aplikację.
W przypadku aplikacji, które w niewielkim stopniu korzystają z pakietu SDK Firebase na potrzeby internetu (np. aplikacji, które wykonują tylko proste wywołanie interfejsów Authentication), może być praktyczne przekształcenie starszego kodu z przestrzenią nazw bez używania bibliotek zgodności. Jeśli uaktualniasz taką aplikację, możesz postępować zgodnie z instrukcjami w tym przewodniku dotyczącymi „modułowego interfejsu API” bez używania bibliotek zgodności.
Informacje o procesie uaktualniania
Każdy etap procesu uaktualniania jest tak zaplanowany, aby można było zakończyć edytowanie kodu źródłowego aplikacji, a następnie skompilować i uruchomić ją bez żadnych problemów. Podsumowując, aby przejść na wyższą wersję aplikacji:
- Dodaj do aplikacji biblioteki modułowe i biblioteki zgodności.
- Zaktualizuj instrukcje importu w kodzie, aby były zgodne z biblioteką zgodności.
- Zmień kod pojedynczego produktu (np. Authentication) na styl modułowy.
- Opcjonalnie: w tym momencie usuń bibliotekę zgodności Authentication i kod zgodności Authentication, aby przed kontynuowaniem zmniejszyć rozmiar aplikacji na urządzeniach Authentication.
- Przeprowadź refaktoryzację funkcji dla każdego produktu (np. Cloud Firestore, FCM itp.) do stylu modułowego, kompilując i testując, aż wszystkie obszary zostaną ukończone.
- Zaktualizuj kod inicjowania do stylu modułowego.
- Usuń z aplikacji wszystkie pozostałe instrukcje i kod zgodności.
Pobieranie najnowszej wersji pakietu SDK
Aby rozpocząć, pobierz biblioteki modułowe i biblioteki zgodności za pomocą npm:
npm i firebase@12.0.0 # OR yarn add firebase@12.0.0
Aktualizowanie importów do wersji zgodnej
Aby kod działał po zaktualizowaniu zależności, zmień instrukcje importowania, tak 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';
Przekształcanie kodu w stylu modułowym
Interfejsy API z przestrzenią nazw opierają się na wzorcu przestrzeni nazw i usługi połączonych kropkami, ale podejście modułowe oznacza, że kod będzie zorganizowany głównie wokół funkcji. W interfejsie API w formie modułów pakiet firebase/app
i inne pakiety nie zwracają kompleksowego eksportu zawierającego wszystkie metody z pakietu. Zamiast tego pakiety eksportują poszczególne funkcje.
W modułowym interfejsie API usługi są przekazywane jako pierwszy argument, a funkcja wykorzystuje szczegóły usługi do wykonania pozostałych czynności. Przyjrzyjmy się, jak to działa, na 2 przykładach, w których refaktoryzujemy wywołania interfejsów API Authentication i Cloud Firestore.
Przykład 1. Refaktoryzacja funkcji Authentication
Przed: compat
Kod zgodności jest identyczny z kodem w przestrzeni nazw, ale zmieniły się importy.
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
const auth = firebase.auth();
auth.onAuthStateChanged(user => {
// Check for user status
});
Po: modułowy
Funkcja getAuth
przyjmuje jako pierwszy parametr wartość firebaseApp
.
Funkcja onAuthStateChanged
nie jest połączona z instancją auth
, jak to ma miejsce w przestrzeni nazw interfejsu API. Zamiast tego jest to funkcja wolna, która jako pierwszy parametr przyjmuje auth
.
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
// Check for user status
});
Aktualizacja obsługi metody uwierzytelniania getRedirectResult
Modułowy interfejs API wprowadza w getRedirectResult
zmianę powodującą niezgodność wsteczną. Gdy nie jest wywoływana żadna operacja przekierowania, interfejs API modułowy zwraca null
, w przeciwieństwie do interfejsu API z przestrzenią nazw, który zwracał UserCredential
z użytkownikiem null
.
Przed: compat
const result = await auth.getRedirectResult()
if (result.user === null && result.credential === null) {
return null;
}
return result;
Po: modułowy
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
Przed: 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);
});
Po: modułowy
Funkcja getFirestore
przyjmuje jako pierwszy parametr wartość firebaseApp
, która została zwrócona przez funkcję initializeApp
w poprzednim przykładzie. Zwróć uwagę, że kod tworzący zapytanie w modułowym interfejsie API bardzo się różni. Nie ma łańcuchów wywołań, a metody takie jak query
czy where
są teraz udostępniane jako funkcje swobodne.
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łowy interfejs API wprowadza zmianę powodującą niezgodność wsteczną, w której właściwość firestore.DocumentSnapshot.exists
została zmieniona na metodę. Funkcja jest zasadniczo taka sama (sprawdzanie, czy dokument istnieje), ale musisz zmodyfikować kod, aby używać nowszej metody, jak pokazano poniżej:
Before:compat
if (snapshot.exists) {
console.log("the document exists");
}
Po: modułowy
if (snapshot.exists()) {
console.log("the document exists");
}
Przykład 3. Łączenie stylów kodu z przestrzenią nazw i modułowego
Korzystanie z bibliotek zgodności podczas uaktualniania umożliwia dalsze używanie kodu z przestrzenią nazw obok kodu zmodyfikowanego pod kątem modułowego interfejsu API. Oznacza to, że możesz zachować istniejący kod z przestrzenią nazw dla Cloud Firestore, podczas gdy będziesz przekształcać Authentication lub inny kod pakietu SDK Firebase na styl modułowy. Aplikacja będzie się nadal kompilować z użyciem obu stylów kodu. To samo dotyczy kodu interfejsu API z przestrzenią nazw i modułowego w ramach produktu, takiego jak Cloud Firestore. Nowe i stare style kodu mogą współistnieć, o ile importujesz pakiety zgodności:
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ż aplikacja zostanie skompilowana, nie uzyskasz korzyści związanych z rozmiarem aplikacji, dopóki całkowicie nie usuniesz z niej instrukcji i kodu zgodności.
Aktualizowanie kodu inicjowania
Zaktualizuj kod inicjujący aplikacji, aby używać składni modułowej. Ważne jest, aby zaktualizować ten kod po zakończeniu refaktoryzacji całego kodu w aplikacji, ponieważ funkcja firebase.initializeApp()
inicjuje stan globalny zarówno w przypadku interfejsów API zgodnych z wersją starszą, jak i modułowych, a funkcja modułowa initializeApp()
inicjuje tylko stan modułowy.
Przed: compat
import firebase from "firebase/compat/app"
firebase.initializeApp({ /* config */ });
Po: modułowy
import { initializeApp } from "firebase/app"
const firebaseApp = initializeApp({ /* config */ });
Usuwanie kodu zgodności
Aby w pełni wykorzystać zalety modułowego interfejsu API, musisz ostatecznie przekształcić wszystkie wywołania w styl modułowy pokazany powyżej i usunąć z kodu wszystkie instrukcje import "firebase/compat/*
. Po zakończeniu nie powinno być już odwołań do firebase.*
globalnej przestrzeni nazw ani żadnego innego kodu w stylu interfejsu API z przestrzenią nazw.
Korzystanie z biblioteki zgodności z okna
Modułowy interfejs API jest zoptymalizowany pod kątem współpracy z modułami, a nie z obiektem window
przeglądarki. W poprzednich wersjach biblioteki można było wczytywać Firebase i zarządzać nim za pomocą przestrzeni nazw window.firebase
. Nie zalecamy tego rozwiązania, ponieważ nie pozwala ono na eliminowanie nieużywanego kodu.
Wersja pakietu SDK JavaScript zgodna z wcześniejszymi wersjami działa jednak z window
dla deweloperów, którzy wolą nie rozpoczynać od razu ścieżki uaktualniania modułowego.
<script src="https://www.gstatic.com/firebasejs/12.0.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/12.0.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/12.0.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 pod maską kodu modułowego i udostępnia go z tym samym interfejsem API co interfejs API z przestrzenią nazw. Oznacza to, że szczegółowe informacje znajdziesz w dokumentacji interfejsu API z przestrzenią nazw i w fragmentach kodu z przestrzenią nazw. Ta metoda nie jest zalecana do długotrwałego użytku, ale może być dobrym początkiem przejścia na w pełni modułową bibliotekę.
Zalety i ograniczenia modułowego pakietu SDK
W porównaniu z poprzednimi wersjami w pełni modułowy pakiet SDK ma te zalety:
- Modułowy pakiet SDK umożliwia znaczne zmniejszenie rozmiaru aplikacji. Korzysta z nowoczesnego formatu modułu JavaScript, co umożliwia stosowanie techniki „tree shaking”, w której importujesz tylko te artefakty, których potrzebuje Twoja aplikacja. W zależności od aplikacji usuwanie nieużywanego kodu za pomocą modułowego pakietu SDK może zmniejszyć rozmiar aplikacji o 80% w porównaniu z podobną aplikacją utworzoną przy użyciu interfejsu API z przestrzenią nazw.
- Modułowy pakiet SDK będzie nadal korzystać z bieżącego rozwoju funkcji, a interfejs API z przestrzenią nazw nie będzie.