Những ứng dụng đang dùng các hàm thế hệ 1 nên cân nhắc chuyển sang thế hệ 2 bằng cách làm theo các bước trong hướng dẫn này. Các hàm thế hệ 2 sử dụng Cloud Run để cung cấp hiệu suất tốt hơn, cấu hình tốt hơn, giám sát tốt hơn và nhiều tính năng khác.
Các ví dụ trong trang này giả định bạn đang sử dụng JavaScript với các mô-đun CommonJS
(nhập kiểu require
), nhưng những nguyên tắc tương tự áp dụng cho JavaScript với ESM
(Nhập kiểu import … from
) và TypeScript.
Quá trình di chuyển
Các hàm thế hệ 1 và thế hệ 2 có thể cùng tồn tại cạnh nhau trong cùng một tệp. Chiến dịch này cho phép di chuyển dễ dàng từng phần khi bạn đã sẵn sàng. Bạn nên di chuyển từng hàm một, thực hiện kiểm thử và xác minh trước khi tiếp tục.
Xác minh phiên bản Firebase CLI và firebase-function
Đảm bảo bạn đang sử dụng Firebase CLI phiên bản 12.00
và
firebase-functions
phiên bản 4.3.0
. Mọi phiên bản mới hơn đều sẽ hỗ trợ thế hệ thứ 2 dưới dạng
thế hệ 1.
Cập nhật lệnh nhập
Nhập các hàm thế hệ thứ 2 từ gói con v2
trong SDK firebase-functions
.
Đường dẫn nhập khác này là tất cả những gì Giao diện dòng lệnh (CLI) của Firebase cần để xác định xem
triển khai mã hàm của bạn dưới dạng hàm thế hệ 1 hoặc thế hệ 2.
Gói con v2
là theo mô-đun và bạn chỉ nên nhập
mà bạn cần.
Trước: thế hệ thứ 1
const functions = require("firebase-functions/v1");
Sau: thế hệ thứ 2
// explicitly import each trigger
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
Cập nhật định nghĩa của điều kiện kích hoạt
Vì SDK thế hệ thứ 2 ưu tiên tính năng nhập mô-đun, hãy cập nhật định nghĩa của điều kiện kích hoạt thành phản ánh các lệnh nhập đã thay đổi ở bước trước.
Các đối số được truyền đến lệnh gọi lại cho một số điều kiện kích hoạt đã thay đổi. Trong phần này
Ví dụ: xin lưu ý rằng các đối số cho lệnh gọi lại onDocumentCreated
đã được
được hợp nhất thành một đối tượng event
duy nhất. Ngoài ra, một số điều kiện kích hoạt có
các tính năng cấu hình mới thuận tiện, chẳng hạn như cors
của điều kiện kích hoạt onRequest
.
Trước: thế hệ thứ 1
const functions = require("firebase-functions/v1");
exports.date = functions.https.onRequest((req, res) => {
// ...
});
exports.uppercase = functions.firestore
.document("my-collection/{docId}")
.onCreate((change, context) => {
// ...
});
Sau: thế hệ thứ 2
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
exports.date = onRequest({cors: true}, (req, res) => {
// ...
});
exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
/* ... */
});
Sử dụng cấu hình có tham số
Các hàm thế hệ 2 ngừng hỗ trợ functions.config
và thay vào đó là một giao diện an toàn hơn để xác định các tham số cấu hình theo cách khai báo bên trong cơ sở mã của bạn. Với mô-đun params
mới, CLI chặn hoạt động triển khai trừ phi tất cả tham số đều có giá trị hợp lệ, đảm bảo rằng một hàm sẽ không được triển khai khi thiếu cấu hình.
Di chuyển sang gói con params
Nếu đang sử dụng cấu hình môi trường bằng functions.config
, bạn
có thể di chuyển cấu hình hiện tại của mình sang
cấu hình có tham số.
Trước: thế hệ thứ 1
const functions = require("firebase-functions/v1");
exports.date = functions.https.onRequest((req, res) => {
const date = new Date();
const formattedDate =
date.toLocaleDateString(functions.config().dateformat);
// ...
});
Sau: thế hệ thứ 2
const {onRequest} = require("firebase-functions/v2/https");
const {defineString} = require("firebase-functions/params");
const dateFormat = defineString("DATE_FORMAT");
exports.date = onRequest((req, res) => {
const date = new Date();
const formattedDate = date.toLocaleDateString(dateFormat.value());
// ...
});
Đặt giá trị thông số
Trong lần đầu tiên bạn triển khai, Firebase CLI sẽ nhắc đối với tất cả các giá trị của
và lưu các giá trị vào tệp dotenv. Để xuất
các giá trị function.config, chạy firebase functions:config:export
.
Để tăng mức độ an toàn, bạn cũng có thể chỉ định loại tham số và quy tắc xác thực.
Trường hợp đặc biệt: Khoá API
Mô-đun params
tích hợp với Cloud Secret Manager, mô-đun này cung cấp
kiểm soát quyền truy cập chi tiết vào các giá trị nhạy cảm như khoá API. Xem
tham số bí mật
để biết thêm thông tin.
Trước: thế hệ thứ 1
const functions = require("firebase-functions/v1");
exports.getQuote = functions.https.onRequest(async (req, res) => {
const quote = await fetchMotivationalQuote(functions.config().apiKey);
// ...
});
Sau: thế hệ thứ 2
const {onRequest} = require("firebase-functions/v2/https");
const {defineSecret} = require("firebase-functions/params");
// Define the secret parameter
const apiKey = defineSecret("API_KEY");
exports.getQuote = onRequest(
// make the secret available to this function
{ secrets: [apiKey] },
async (req, res) => {
// retrieve the value of the secret
const quote = await fetchMotivationalQuote(apiKey.value());
// ...
}
);
Đặt tuỳ chọn thời gian chạy
Cấu hình tuỳ chọn thời gian chạy đã thay đổi giữa thế hệ 1 và thế hệ 2. Thế hệ thứ 2 cũng bổ sung một tính năng mới để đặt tuỳ chọn cho tất cả hàm.
Trước: thế hệ thứ 1
const functions = require("firebase-functions/v1");
exports.date = functions
.runWith({
// Keep 5 instances warm for this latency-critical function
minInstances: 5,
})
// locate function closest to users
.region("asia-northeast1")
.https.onRequest((req, res) => {
// ...
});
exports.uppercase = functions
// locate function closest to users and database
.region("asia-northeast1")
.firestore.document("my-collection/{docId}")
.onCreate((change, context) => {
// ...
});
Sau: thế hệ thứ 2
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
const {setGlobalOptions} = require("firebase-functions/v2");
// locate all functions closest to users
setGlobalOptions({ region: "asia-northeast1" });
exports.date = onRequest({
// Keep 5 instances warm for this latency-critical function
minInstances: 5,
}, (req, res) => {
// ...
});
exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
/* ... */
});
Dùng mô hình đồng thời
Một lợi thế quan trọng của hàm thế hệ 2 là khả năng của một hàm duy nhất phân phối nhiều yêu cầu cùng một lúc. Điều này có thể làm giảm đáng kể số lần khởi động nguội mà người dùng cuối gặp phải. Theo mặc định, mô hình đồng thời là đặt ở 80, nhưng bạn có thể đặt thành bất kỳ giá trị nào từ 1 đến 1000:
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// set concurrency value
concurrency: 500
},
(req, res) => {
// ...
});
Việc điều chỉnh mô hình đồng thời có thể cải thiện hiệu suất và giảm chi phí của các hàm. Tìm hiểu thêm về tính năng đồng thời trong phần Cho phép các yêu cầu đồng thời.
Kiểm tra việc sử dụng biến toàn cục
Các hàm thế hệ 1 được viết mà không lưu ý đến mô hình đồng thời có thể sử dụng các biến toàn cục được đặt và đọc trên mỗi yêu cầu. Khi tính năng đồng thời được bật và một thực thể bắt đầu xử lý nhiều yêu cầu cùng một lúc nên có thể gây ra lỗi trong hàm của bạn khi các yêu cầu đồng thời sẽ bắt đầu cài đặt và đọc các biến toàn cục đồng thời.
Trong khi nâng cấp, bạn có thể đặt CPU của hàm thành gcf_gen1
và đặt concurrency
thành 1 để khôi phục hành vi của thế hệ 1:
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// TEMPORARY FIX: remove concurrency
cpu: "gcf_gen1",
concurrency: 1
},
(req, res) => {
// ...
});
Tuy nhiên, đây không phải là biện pháp khắc phục lâu dài vì sẽ mất các lợi thế về hiệu suất của các hàm thế hệ thứ 2. Thay vào đó, hãy kiểm tra việc sử dụng trong các hàm của bạn và xoá các cài đặt tạm thời này khi bạn sẵn sàng.
Di chuyển lưu lượng truy cập sang các hàm thế hệ thứ 2 mới
Tương tự như khi thay đổi vùng hoặc loại điều kiện kích hoạt của một hàm, bạn cần đặt tên mới cho hàm thế hệ 2 và từ từ di chuyển lưu lượng truy cập đến hàm đó.
Bạn không thể nâng cấp một hàm từ thế hệ 1 lên thế hệ 2 có cùng tên rồi chạy firebase deploy
. Thao tác này sẽ dẫn đến lỗi:
Upgrading from GCFv1 to GCFv2 is not yet supported. Please delete your old function or wait for this feature to be ready.
Trước khi thực hiện các bước này, đầu tiên hãy đảm bảo rằng hàm của bạn không thay đổi vì cả phiên bản mới và phiên bản cũ của hàm sẽ chạy cùng lúc trong quá trình thay đổi. Ví dụ: nếu bạn có một hàm thế hệ 1 phản hồi để ghi các sự kiện trong Firestore, hãy đảm bảo rằng việc phản hồi lệnh ghi hai lần, một lần ở hàm thế hệ 1 và một lần ở hàm thế hệ 2, để phản hồi những sự kiện đó, ứng dụng của bạn sẽ ở trạng thái nhất quán.
- Đổi tên hàm trong mã hàm. Ví dụ: đổi tên
resizeImage
thànhresizeImageSecondGen
. - Triển khai hàm này để cả hàm thế hệ 1 và thế hệ 2 ban đầu đều đang chạy.
- Trong trường hợp có thể gọi, Hàng đợi tác vụ và trình kích hoạt HTTP, hãy bắt đầu trỏ tất cả máy khách đến hàm thế hệ 2 bằng cách cập nhật mã máy khách với tên hoặc URL của hàm thế hệ 2.
- Với điều kiện kích hoạt ở chế độ nền, cả hàm thế hệ 1 và thế hệ 2 đều sẽ phản hồi mọi sự kiện ngay khi triển khai.
- Khi tất cả lưu lượng truy cập bị tắt, hãy xoá hàm thế hệ 1 bằng lệnh
firebase functions:delete
của firebase CLI.- Bạn có thể đổi tên hàm thế hệ 2 để khớp với tên của hàm thế hệ 1 (không bắt buộc).