如果應用程式使用任何命名空間的 Firebase Web API (從 compat
程式庫到 8 以上版本),請考慮按照本指南中的操作說明,遷移至模組化 API。
本指南假設您熟悉命名空間 API,並會利用 webpack 或 Rollup 等模組整合工具,升級及持續開發模組化應用程式。
強烈建議您在開發環境中使用模組打包工具。如果沒有使用,就無法享有模組化 API 的主要優點,也就是縮減應用程式大小。您需要 npm 或 yarn 才能安裝 SDK。
本指南中的升級步驟是以虛構的網頁應用程式為基礎,該應用程式使用 Authentication 和 Cloud Firestore SDK。透過這些範例,您可以掌握升級所有支援的 Firebase 網頁 SDK 所需的概念和實用步驟。
關於命名空間 (compat
) 程式庫
Firebase 網頁 SDK 提供兩種類型的程式庫:
- 模組化:全新 API 介面,可簡化樹狀結構搖動 (移除未使用的程式碼),盡量縮小網路應用程式的大小並提升速度。
- 具命名空間 (
compat
):這個 API 介面與舊版 SDK 完全相容,因此您可以升級,不必一次變更所有 Firebase 程式碼。與命名空間對應項目相比,相容性程式庫在大小或效能方面幾乎沒有優勢。
本指南假設您會利用 Compat 程式庫簡化升級作業。這些程式庫可讓您繼續使用命名空間程式碼,以及為模組化 API 重構的程式碼。這表示您在升級過程中,可以更輕鬆地編譯及偵錯應用程式。
如果應用程式使用 Firebase 網頁 SDK 的程度很低 (例如只對 Authentication API 進行簡單呼叫),或許可以不使用相容性程式庫,直接重構舊版命名空間程式碼。如果您要升級這類應用程式,可以按照本指南中「模組化 API」的操作說明,不必使用相容性程式庫。
升級程序說明
升級程序的每個步驟都有範圍,因此您可以完成編輯應用程式的來源,然後編譯及執行應用程式,不會發生中斷情形。總之,升級應用程式的步驟如下:
- 將模組化程式庫和相容性程式庫新增至應用程式。
- 更新程式碼中的匯入陳述式,以確保相容性。
- 將單一產品 (例如 Authentication) 的程式碼重構為模組化樣式。
- 選用:此時,請移除 Authentication 相容性程式庫和 Authentication 的相容性程式碼,以便在繼續操作前,先享有 Authentication 帶來的應用程式大小優勢。
- 將各項產品的函式 (例如 Cloud Firestore、FCM 等) 重構為模組化樣式,並編譯及測試,直到所有區域都完成為止。
- 將初始化程式碼更新為模組化樣式。
- 從應用程式中移除所有剩餘的相容性陳述式和相容性程式碼。
取得最新版 SDK
如要開始使用,請透過 npm 取得模組化程式庫和相容性程式庫:
npm i firebase@12.0.0 # OR yarn add firebase@12.0.0
將匯入內容更新為相容
為確保程式碼在更新依附元件後仍能正常運作,請變更匯入陳述式,改用每個匯入項目的「compat」版本。例如:
變更前:8 以下版本
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
變更後:compat
// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
重構為模組化樣式
雖然命名空間 API 是以點鏈結命名空間和服務模式為基礎,但模組化方法表示您的程式碼主要會圍繞函式來組織。在模組化 API 中,firebase/app
套件和其他套件不會傳回包含套件中所有方法的完整匯出內容。而是匯出個別函式。
在模組化 API 中,服務會做為第一個引數傳遞,然後函式會使用服務詳細資料執行其餘作業。讓我們透過兩個範例,瞭解如何重構對 Authentication 和 Cloud Firestore API 的呼叫。
範例 1:重構 Authentication 函式
變更前:compat
相容性程式碼與命名空間程式碼相同,但匯入項目已變更。
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
const auth = firebase.auth();
auth.onAuthStateChanged(user => {
// Check for user status
});
變更後:模組化
getAuth
函式會將 firebaseApp
做為第一個參數。onAuthStateChanged
函式不會像命名空間 API 那樣從 auth
執行個體鏈結,而是以 auth
做為第一個參數的自由函式。
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
// Check for user status
});
更新驗證方法 getRedirectResult
的處理方式
模組化 API 在 getRedirectResult
中導入了破壞性變更。如果未呼叫重新導向作業,模組化 API 會傳回 null
,而非命名空間 API 傳回的 UserCredential
(含 null
使用者)。
變更前:compat
const result = await auth.getRedirectResult()
if (result.user === null && result.credential === null) {
return null;
}
return result;
變更後:模組化
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;
範例 2:重構 Cloud Firestore 函式
變更前: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);
});
變更後:模組化
getFirestore
函式會將 firebaseApp
做為第一個參數,而 firebaseApp
是在先前的範例中從 initializeApp
傳回。請注意,模組化 API 中形成查詢的程式碼非常不同,沒有鏈結,且 query
或 where
等方法現在會公開為免費函式。
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());
});
更新 Firestore DocumentSnapshot.exists
的參照
模組化 API 導入了破壞性變更,將 firestore.DocumentSnapshot.exists
屬性變更為方法。功能基本上相同 (測試文件是否存在),但您必須重構程式碼,才能使用較新的方法,如下所示:
變更前:compat
if (snapshot.exists) {
console.log("the document exists");
}
變更後:模組化
if (snapshot.exists()) {
console.log("the document exists");
}
範例 3:合併命名空間和模組化程式碼樣式
升級期間使用相容性程式庫,可讓您繼續使用命名空間程式碼,以及為模組化 API 重構的程式碼。也就是說,您可以保留 Cloud Firestore 的現有命名空間程式碼,同時將 Authentication 或其他 Firebase SDK 程式碼重構為模組化樣式,並使用這兩種程式碼樣式成功編譯應用程式。產品內的命名空間和模組化 API 程式碼也是如此,例如 Cloud Firestore。只要匯入相容性套件,新舊程式碼樣式就能並存:
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import { getDoc } from 'firebase/firestore'
const docRef = firebase.firestore().doc();
getDoc(docRef);
請注意,雖然應用程式會編譯,但您必須從應用程式中完全移除相容性陳述式和程式碼,才能享有模組化程式碼帶來的應用程式大小優勢。
更新初始化程式碼
更新應用程式的初始化程式碼,改用模組化語法。完成應用程式中所有程式碼的重構作業後,請務必更新這段程式碼,因為 firebase.initializeApp()
會初始化相容性和模組化 API 的全域狀態,而模組化 initializeApp()
函式只會初始化模組化狀態。
變更前:compat
import firebase from "firebase/compat/app"
firebase.initializeApp({ /* config */ });
變更後:模組化
import { initializeApp } from "firebase/app"
const firebaseApp = initializeApp({ /* config */ });
移除相容性程式碼
如要享有模組化 API 的大小優勢,您最終應將所有呼叫轉換為上述模組化樣式,並從程式碼中移除所有 import "firebase/compat/*
陳述式。完成後,命名空間 API 樣式中不應再有對 firebase.*
全域命名空間或任何其他程式碼的參照。
從視窗使用 compat 程式庫
模組化 API 專為搭配模組使用而設計,而非瀏覽器的 window
物件。舊版程式庫允許使用 window.firebase
命名空間載入及管理 Firebase。今後不建議使用這種做法,因為這樣無法排除未使用的程式碼。不過,JavaScript SDK 的相容版本適用於window
,開發人員可選擇暫時不開始模組化升級程序。
<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>
相容性程式庫會在幕後使用模組化程式碼,並提供與命名空間 API 相同的 API;這表示您可以參閱命名空間 API 參考資料和命名空間程式碼片段,瞭解詳細資料。不建議長期使用這個方法,但可以做為升級至完全模組化程式庫的起點。
模組化 SDK 的優點和限制
與舊版相比,完全模組化的 SDK 具有下列優勢:
- 模組化 SDK 可大幅縮減應用程式大小。 採用現代 JavaScript 模組格式,可讓您執行「樹狀結構修剪」做法,只匯入應用程式需要的構件。視應用程式而定,使用模組化 SDK 進行樹狀結構修剪,可比使用命名空間 API 建構的類似應用程式,減少 80% 的 KB。
- 模組化 SDK 將持續受惠於持續開發的功能,但命名空間 API 不會。