如果應用程式使用任何命名空間 Firebase Web API (從 compat 程式庫到第 8 版或更早版本),請考慮按照本指南中的操作說明,遷移至模組化 API。
本指南假設您熟悉命名空間 API,並會使用 webpack 或 Rollup 等模組整合工具,進行升級及持續開發模組化應用程式。
強烈建議您在開發環境中使用模組套件。如果不使用,就無法享有模組化 API 的主要優點,也就是縮減應用程式大小。您需要 npm 或 yarn 才能安裝 SDK。
本指南中的升級步驟,是以使用 Authentication 和 Cloud Firestore SDK 的虛構網頁應用程式為基礎。透過這些範例,您可以掌握升級所有支援的 Firebase Web SDK 所需的概念和實際步驟。
關於命名空間 (compat) 程式庫
Firebase 網頁 SDK 提供兩種程式庫:
- 模組化:全新的 API 介面,旨在促進 tree-shaking (移除未使用的程式碼),讓網頁應用程式盡可能縮小並加快速度。
- 命名空間 (
compat):熟悉的 API 介面,與舊版 SDK 完全相容,可讓您升級,而不必一次變更所有 Firebase 程式碼。與命名空間對應項目相比,相容性程式庫在大小或效能方面幾乎沒有優勢。
本指南假設您會利用相容程式庫來簡化升級作業。這些程式庫可讓您繼續使用命名空間程式碼,以及針對模組化 API 重構的程式碼。這表示您在升級過程中,可以更輕鬆地編譯及偵錯應用程式。
如果應用程式與 Firebase Web SDK 的接觸極少 (例如,應用程式只對 Authentication API 進行簡單呼叫),則在不使用相容程式庫的情況下,重構舊版命名空間程式碼可能較為實際。如要升級這類應用程式,請按照本指南中「模組化 API」的操作說明操作,不需使用相容程式庫。
升級程序簡介
升級程序的每個步驟都有範圍,因此您可以完成應用程式來源的編輯,然後編譯並執行,而不會中斷。總之,升級應用程式的步驟如下:
- 將模組化程式庫和相容程式庫新增至應用程式。
- 將程式碼中的匯入陳述式更新為 compat。
- 將單一產品 (例如 Authentication) 的程式碼重構為模組化樣式。
- 選用:此時,請移除 Authentication 相容性程式庫和 Authentication 的相容性程式碼,以便在繼續操作前,實現 Authentication 的應用程式大小優勢。
- 將各產品的功能 (例如 Cloud Firestore、FCM 等) 重構為模組化樣式,並進行編譯和測試,直到所有區域都完成為止。
- 將初始化程式碼更新為模組化樣式。
- 從應用程式中移除所有剩餘的相容性陳述式和相容性程式碼。
取得最新版本 SDK
首先,請使用 npm 取得模組化程式庫和相容程式庫:
npm i firebase@13.2.0 # OR yarn add firebase@13.2.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 做為第一個參數,這個參數是先前範例中由 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 屬性變更為方法。功能基本上相同 (測試文件是否存在),但您必須重構程式碼,改用較新的方法,如下所示:
Before: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/* 陳述式。完成後,不應再有任何參照 firebase.* 全域命名空間,或任何其他命名空間 API 樣式的程式碼。
使用視窗中的相容程式庫
模組化 API 經過最佳化,可與模組搭配使用,而非瀏覽器的 window 物件。舊版程式庫允許使用 window.firebase 命名空間載入及管理 Firebase。我們不建議繼續使用這種做法,因為這無法排除未使用的程式碼。不過,如果開發人員不想立即開始模組化升級,JavaScript SDK 的相容版本可與 window 搭配使用。
<script src="https://www.gstatic.com/firebasejs/13.2.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/13.2.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/13.2.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 模組格式,允許「tree shaking」做法,只匯入應用程式需要的構件。視應用程式而定,使用模組化 SDK 進行 tree shaking (移除沒用到的程式碼),可讓應用程式的大小比使用命名空間 API 建構的類似應用程式減少 80%。
- 模組化 SDK 會持續受益於新功能開發,但命名空間 API 則不會。