Các ứng dụng sử dụng bất kỳ API Web Firebase nào có không gian tên, từ các thư viện compat
trở về phiên bản 8 trở xuống, nên cân nhắc việc di chuyển sang API mô-đun bằng cách làm theo hướng dẫn trong hướng dẫn này.
Hướng dẫn này giả định rằng bạn đã quen thuộc với API không gian tên và bạn sẽ tận dụng trình đóng gói mô-đun như webpack hoặc Rollup để nâng cấp và phát triển ứng dụng mô-đun đang diễn ra.
Bạn nên sử dụng trình đóng gói mô-đun trong môi trường phát triển. Nếu không sử dụng, bạn sẽ không thể tận dụng các lợi ích chính của API mô-đun trong việc giảm kích thước ứng dụng. Bạn sẽ cần npm hoặc yarn để cài đặt SDK.
Các bước nâng cấp trong hướng dẫn này sẽ dựa trên một ứng dụng web ảo sử dụng SDK Authentication và Cloud Firestore. Bằng cách làm theo các ví dụ, bạn có thể nắm vững các khái niệm và bước thực tế cần thiết để nâng cấp tất cả SDK Web Firebase được hỗ trợ.
Giới thiệu về thư viện có không gian tên (compat
)
Có hai loại thư viện dành cho SDK Firebase Web:
- Modular (Mô-đun) – một giao diện API mới được thiết kế để hỗ trợ tính năng loại bỏ mã không dùng đến (xoá mã không dùng đến) nhằm giúp ứng dụng web của bạn nhỏ gọn và nhanh nhất có thể.
- Được đặt tên không gian (
compat
) – một nền tảng API quen thuộc hoàn toàn tương thích với các phiên bản SDK trước đó, cho phép bạn nâng cấp mà không cần thay đổi tất cả mã Firebase cùng một lúc. Thư viện tương thích có ít hoặc không có lợi thế về kích thước hoặc hiệu suất so với các thư viện có tên.
Hướng dẫn này giả định rằng bạn sẽ tận dụng các thư viện tương thích để hỗ trợ quá trình nâng cấp. Các thư viện này cho phép bạn tiếp tục sử dụng mã không gian tên cùng với mã được tái cấu trúc cho API mô-đun. Điều này có nghĩa là bạn có thể biên dịch và gỡ lỗi ứng dụng dễ dàng hơn khi thực hiện quy trình nâng cấp.
Đối với các ứng dụng có mức độ tiếp xúc rất nhỏ với SDK Firebase Web (ví dụ: một ứng dụng chỉ thực hiện một lệnh gọi đơn giản đến các API Authentication), bạn có thể tái cấu trúc mã có không gian tên cũ mà không cần sử dụng thư viện tương thích. Nếu đang nâng cấp một ứng dụng như vậy, bạn có thể làm theo hướng dẫn trong hướng dẫn này về "API mô-đun" mà không cần sử dụng thư viện tương thích.
Giới thiệu về quy trình nâng cấp
Mỗi bước của quy trình nâng cấp đều được xác định phạm vi để bạn có thể hoàn tất việc chỉnh sửa nguồn cho ứng dụng, sau đó biên dịch và chạy ứng dụng mà không bị gián đoạn. Tóm lại, sau đây là những việc bạn cần làm để nâng cấp ứng dụng:
- Thêm thư viện mô-đun và thư viện tương thích vào ứng dụng.
- Cập nhật câu lệnh nhập trong mã thành tương thích.
- Tái cấu trúc mã cho một sản phẩm (ví dụ: Authentication) thành kiểu mô-đun.
- Không bắt buộc: tại thời điểm này, hãy xoá thư viện tương thích Authentication và mã tương thích cho Authentication để nhận ra lợi ích về kích thước ứng dụng cho Authentication trước khi tiếp tục.
- Tái cấu trúc các hàm cho từng sản phẩm (ví dụ: Cloud Firestore, FCM, v.v.) theo kiểu mô-đun, biên dịch và kiểm thử cho đến khi hoàn tất tất cả các khu vực.
- Cập nhật mã khởi tạo thành kiểu mô-đun.
- Xoá tất cả câu lệnh tương thích và mã tương thích còn lại khỏi ứng dụng.
Tải phiên bản SDK mới nhất
Để bắt đầu, hãy tải thư viện mô-đun và thư viện tương thích bằng npm:
npm i firebase@11.3.0 # OR yarn add firebase@11.3.0
Cập nhật các mục nhập thành tương thích
Để mã của bạn vẫn hoạt động sau khi cập nhật các phần phụ thuộc, hãy thay đổi câu lệnh nhập để sử dụng phiên bản "compat" của mỗi lệnh nhập. Ví dụ:
Trước: phiên bản 8 trở về trước
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
Sau: compat
// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
Tái cấu trúc thành kiểu mô-đun
Mặc dù các API có không gian tên dựa trên mẫu dịch vụ và không gian tên được nối bằng dấu chấm, nhưng phương pháp mô-đun có nghĩa là mã của bạn sẽ được sắp xếp chủ yếu xung quanh các hàm. Trong API mô-đun, gói firebase/app
và các gói khác không trả về một tệp xuất toàn diện chứa tất cả các phương thức từ gói. Thay vào đó, các gói sẽ xuất từng hàm riêng lẻ.
Trong API mô-đun, các dịch vụ được truyền dưới dạng đối số đầu tiên, sau đó hàm sẽ sử dụng thông tin chi tiết của dịch vụ để thực hiện phần còn lại. Hãy cùng xem cách hoạt động của tính năng này trong hai ví dụ tái cấu trúc các lệnh gọi đến API Authentication và Cloud Firestore.
Ví dụ 1: tái cấu trúc hàm Authentication
Trước: compat
Mã tương thích giống hệt với mã có không gian tên, nhưng các lệnh nhập đã thay đổi.
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
const auth = firebase.auth();
auth.onAuthStateChanged(user => {
// Check for user status
});
Sau: mô-đun
Hàm getAuth
nhận firebaseApp
làm tham số đầu tiên.
Hàm onAuthStateChanged
không được tạo chuỗi từ thực thể auth
như trong API có không gian tên; thay vào đó, đây là một hàm tự do lấy auth
làm tham số đầu tiên.
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
// Check for user status
});
Cập nhật cách xử lý phương thức Xác thực getRedirectResult
API mô-đun giới thiệu một thay đổi có thể gây lỗi trong getRedirectResult
. Khi không có thao tác chuyển hướng nào được gọi, API mô-đun sẽ trả về null
, trái ngược với API có không gian tên, API này trả về UserCredential
với người dùng null
.
Trước: compat
const result = await auth.getRedirectResult()
if (result.user === null && result.credential === null) {
return null;
}
return result;
Sau: mô-đun
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;
Ví dụ 2: tái cấu trúc hàm Cloud Firestore
Trước: 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);
});
Sau: mô-đun
Hàm getFirestore
lấy firebaseApp
làm tham số đầu tiên, tham số này được trả về từ initializeApp
trong ví dụ trước. Lưu ý cách mã để tạo truy vấn rất khác trong API mô-đun; không có chuỗi và các phương thức như query
hoặc where
hiện được hiển thị dưới dạng hàm miễn phí.
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());
});
Cập nhật các tệp tham chiếu đến Firestore DocumentSnapshot.exists
API mô-đun giới thiệu một thay đổi có thể gây lỗi, trong đó thuộc tính firestore.DocumentSnapshot.exists
đã được thay đổi thành một phương thức. Về cơ bản, chức năng này giống nhau (kiểm thử xem tài liệu có tồn tại hay không) nhưng bạn phải tái cấu trúc mã để sử dụng phương thức mới hơn như sau:
Before:compat
if (snapshot.exists) {
console.log("the document exists");
}
Sau: mô-đun
if (snapshot.exists()) {
console.log("the document exists");
}
Ví dụ 3: kết hợp các kiểu mã có không gian tên và mô-đun
Việc sử dụng thư viện tương thích trong quá trình nâng cấp cho phép bạn tiếp tục sử dụng mã được đặt trong không gian tên cùng với mã được tái cấu trúc cho API mô-đun. Điều này có nghĩa là bạn có thể giữ lại mã không gian tên hiện có cho Cloud Firestore trong khi tái cấu trúc Authentication hoặc mã SDK Firebase khác thành kiểu mô-đun và vẫn biên dịch thành công ứng dụng bằng cả hai kiểu mã. Điều này cũng đúng với mã API mô-đun và không gian tên trong một sản phẩm như Cloud Firestore; các kiểu mã mới và cũ có thể tồn tại cùng nhau, miễn là bạn nhập các gói tương thích:
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import { getDoc } from 'firebase/firestore'
const docRef = firebase.firestore().doc();
getDoc(docRef);
Xin lưu ý rằng mặc dù ứng dụng của bạn sẽ biên dịch, nhưng bạn sẽ không nhận được các lợi ích về kích thước ứng dụng của mã mô-đun cho đến khi xoá hoàn toàn các câu lệnh và mã tương thích khỏi ứng dụng.
Cập nhật mã khởi chạy
Cập nhật mã khởi chạy của ứng dụng để sử dụng cú pháp mô-đun. Bạn cần cập nhật mã này sau khi hoàn tất việc tái cấu trúc tất cả mã trong ứng dụng; điều này là do firebase.initializeApp()
khởi chạy trạng thái toàn cục cho cả API tương thích và mô-đun, trong khi hàm initializeApp()
mô-đun chỉ khởi chạy trạng thái cho mô-đun.
Trước: compat
import firebase from "firebase/compat/app"
firebase.initializeApp({ /* config */ });
Sau: mô-đun
import { initializeApp } from "firebase/app"
const firebaseApp = initializeApp({ /* config */ });
Xoá mã tương thích
Để khai thác các lợi ích về kích thước của API mô-đun, cuối cùng, bạn nên chuyển đổi tất cả các lệnh gọi thành kiểu mô-đun như trên và xoá tất cả các câu lệnh import "firebase/compat/*
khỏi mã của mình. Khi bạn hoàn tất, sẽ không còn tham chiếu nào đến không gian tên toàn cục firebase.*
hoặc bất kỳ mã nào khác theo kiểu API có không gian tên.
Sử dụng thư viện tương thích từ cửa sổ
API mô-đun được tối ưu hoá để hoạt động với các mô-đun thay vì đối tượng window
của trình duyệt. Các phiên bản trước của thư viện cho phép tải và quản lý Firebase bằng cách sử dụng không gian tên window.firebase
. Bạn không nên sử dụng phương thức này trong tương lai vì phương thức này không cho phép loại bỏ mã không dùng đến.
Tuy nhiên, phiên bản tương thích của SDK JavaScript hoạt động với window
cho những nhà phát triển không muốn bắt đầu ngay lộ trình nâng cấp mô-đun.
<script src="https://www.gstatic.com/firebasejs/11.3.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/11.3.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/11.3.0/firebase-auth-compat.js"></script>
<script>
const firebaseApp = firebase.initializeApp({ /* Firebase config */ });
const db = firebaseApp.firestore();
const auth = firebaseApp.auth();
</script>
Thư viện khả năng tương thích sử dụng mã mô-đun trong phần nâng cao và cung cấp cho thư viện đó cùng một API như API có không gian tên; điều này có nghĩa là bạn có thể tham khảo tài liệu tham khảo API có không gian tên và các đoạn mã có không gian tên để biết thông tin chi tiết. Bạn không nên sử dụng phương thức này trong thời gian dài, nhưng nên bắt đầu nâng cấp lên thư viện mô-đun đầy đủ.
Lợi ích và hạn chế của SDK mô-đun
SDK được mô-đun hoá hoàn toàn có những ưu điểm sau so với các phiên bản trước:
- SDK mô-đun giúp giảm đáng kể kích thước ứng dụng. Công cụ này sử dụng định dạng Mô-đun JavaScript hiện đại, cho phép các phương pháp "lắc cây" trong đó bạn chỉ nhập các cấu phần phần mềm mà ứng dụng của mình cần. Tuỳ thuộc vào ứng dụng của bạn, việc loại bỏ mã không dùng đến bằng SDK mô-đun có thể làm giảm 80% số kilobyte so với một ứng dụng tương đương được tạo bằng API có không gian tên.
- SDK mô-đun sẽ tiếp tục được hưởng lợi từ việc phát triển tính năng liên tục, trong khi API có không gian tên sẽ không được hưởng lợi.