Thông thường, bạn sẽ cần cấu hình bổ sung cho các hàm, chẳng hạn như khoá API của bên thứ ba hoặc chế độ cài đặt có thể điều chỉnh. Firebase SDK cho Cloud Functions cung cấp cấu hình môi trường tích hợp sẵn để giúp bạn dễ dàng lưu trữ và truy xuất loại dữ liệu này cho dự án của mình.
Bạn có thể chọn trong số các lựa chọn sau:
- Cấu hình có tham số (nên dùng cho hầu hết các trường hợp). Điều này cung cấp cấu hình môi trường được nhập chính xác với các tham số được xác thực tại thời điểm triển khai, giúp ngăn ngừa lỗi và đơn giản hoá việc gỡ lỗi.
- Cấu hình dựa trên tệp của biến môi trường. Với phương pháp này, bạn sẽ tạo tệp dotenv theo cách thủ công để tải các biến môi trường.
Đối với hầu hết các trường hợp sử dụng, bạn nên dùng cấu hình có tham số. Phương pháp này cung cấp các giá trị cấu hình cả trong thời gian chạy và thời gian triển khai, đồng thời quá trình triển khai sẽ bị chặn trừ phi tất cả tham số đều có giá trị hợp lệ. Ngược lại, bạn không thể định cấu hình bằng các biến môi trường tại thời điểm triển khai.
Cấu hình có tham số
Cloud Functions for Firebase cung cấp một giao diện để xác định các tham số cấu hình theo cách khai báo trong cơ sở mã của bạn. Giá trị của các tham số này có sẵn cả trong quá trình triển khai hàm, khi thiết lập các tuỳ chọn triển khai và thời gian chạy, cũng như trong quá trình thực thi. Điều này có nghĩa là CLI sẽ chặn việc triển khai trừ phi tất cả tham số đều có giá trị hợp lệ.
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineInt, defineString } = require('firebase-functions/params');
// Define some parameters
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');
// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
# To use configured parameters inside the config for a function, provide them
# directly. To use them at runtime, call .value() on them.
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')
Khi triển khai một hàm có các biến cấu hình được tham số hoá, trước tiên, Giao diện dòng lệnh (CLI) của Firebase sẽ cố gắng tải các giá trị của biến đó từ tệp .env cục bộ. Nếu các biến này không có trong những tệp đó và không có default nào được đặt, thì CLI sẽ nhắc nhập các giá trị trong quá trình triển khai, sau đó tự động lưu các giá trị đó vào tệp .env có tên là .env.<project_ID> trong thư mục functions/:
$ firebase deploy
i functions: preparing codebase default for deployment
? Enter a string value for ENVIRONMENT: prod
i functions: Writing new parameter values to disk: .env.projectId
…
$ firebase deploy
i functions: Loaded environment variables from .env.projectId
Tuỳ thuộc vào quy trình phát triển, bạn nên thêm tệp .env.<project_ID> đã tạo vào hệ thống quản lý phiên bản.
Sử dụng tham số trong phạm vi chung
Trong quá trình triển khai, mã hàm của bạn sẽ được tải và kiểm tra trước khi các tham số có giá trị thực tế. Điều này có nghĩa là việc tìm nạp giá trị tham số trong
phạm vi toàn cục sẽ dẫn đến lỗi triển khai. Đối với những trường hợp bạn muốn sử dụng một tham số để khởi tạo giá trị chung, hãy sử dụng lệnh gọi lại khởi tạo onInit(). Lệnh gọi lại này chạy trước khi bất kỳ hàm nào chạy trong môi trường thực tế nhưng không được gọi trong thời gian triển khai, vì vậy, đây là nơi an toàn để truy cập vào giá trị của tham số.
Node.js
const { GoogleGenerativeAI } = require('@google/generative-ai');
const { defineSecret } = require('firebase-functions/params');
const { onInit } = require('firebase-functions/v2/core');
const apiKey = defineSecret('GOOGLE_API_KEY');
let genAI;
onInit(() => {
genAI = new GoogleGenerativeAI(apiKey.value());
})
Python
from firebase_functions.core import init
from firebase_functions.params import StringParam, PROJECT_ID
import firebase_admin
import vertexai
location = StringParam("LOCATION")
x = "hello"
@init
def initialize():
# Note: to write back to a global, you'll need to use the "global" keyword
# to avoid creating a new local with the same name.
global x
x = "world"
firebase_admin.initialize_app()
vertexai.init(PROJECT_ID.value, location.value)
Nếu bạn sử dụng các tham số thuộc loại Secret, hãy lưu ý rằng các tham số này chỉ có sẵn trong quá trình thực hiện các hàm đã liên kết với khoá bí mật. Nếu một khoá bí mật chỉ được liên kết trong một số hàm, hãy kiểm tra xem secret.value() có phải là giá trị giả hay không trước khi sử dụng.
Định cấu hình hành vi của CLI
Bạn có thể định cấu hình các tham số bằng một đối tượng Options kiểm soát cách CLI nhắc nhập giá trị. Ví dụ sau đây đặt các tuỳ chọn để xác thực định dạng của số điện thoại, cung cấp một tuỳ chọn lựa chọn đơn giản và tự động điền một tuỳ chọn lựa chọn từ dự án Firebase:
Node.js
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});
const onlyPhoneNumbers = defineString('PHONE_NUMBER', {
input: {
text: {
validationRegex: /\d{3}-\d{3}-\d{4}/,
validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"
},
},
});
const selectedOption = defineString('PARITY', {input: params.select(["odd", "even"])});
const memory = defineInt("MEMORY", {
description: "How much memory do you need?",
input: params.select({ "micro": 256, "chonky": 2048 }),
});
const extensions = defineList("EXTENSIONS", {
description: "Which file types should be processed?",
input: params.multiSelect(["jpg", "tiff", "png", "webp"]),
});
const storageBucket = defineString('BUCKET', {
description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets",
input: params.PICK_STORAGE_BUCKET,
});
Python
from firebase_functions.params import (
StringParam,
ListParam,
TextInput,
SelectInput,
SelectOptions,
ResourceInput,
ResourceType,
)
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam(
"WELCOME_MESSAGE",
default="Hello World",
description="The greeting that is returned to the caller of this function",
)
ONLY_PHONE_NUMBERS = StringParam(
"PHONE_NUMBER",
input=TextInput(
validation_regex="\d{3}-\d{3}-\d{4}",
validation_error_message="Please enter a phone number in the format XXX-YYY-XXX",
),
)
SELECT_OPTION = StringParam(
"PARITY",
input=SelectInput([SelectOptions(value="odd"), SelectOptions(value="even")]),
)
STORAGE_BUCKET = StringParam(
"BUCKET",
input=ResourceInput(type=ResourceType.STORAGE_BUCKET),
description="This will automatically populate the selector field with the deploying Cloud Project's storage buckets",
)
Các loại thông số
Cấu hình có tham số cung cấp kiểu dữ liệu mạnh cho các giá trị tham số, đồng thời hỗ trợ các bí mật từ Trình quản lý bí mật trên đám mây. Các loại được hỗ trợ là:
- Bí mật
- Chuỗi
- Boolean
- Số nguyên
- Nổi
- Danh sách (Node.js)
- Bí mật JSON (Node.js)
Hãy xem paramstài liệu tham khảo về không gian tên để biết thông tin về các hàm dùng để xác định tham số.
Giá trị tham số và biểu thức
Firebase đánh giá các tham số của bạn cả tại thời điểm triển khai và trong khi hàm của bạn đang thực thi. Do có hai môi trường này, bạn phải hết sức cẩn thận khi so sánh các giá trị tham số và khi sử dụng các giá trị đó để đặt tuỳ chọn thời gian chạy cho các hàm.
Để truyền một tham số đến hàm dưới dạng tuỳ chọn thời gian chạy, hãy truyền trực tiếp tham số đó:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineInt } = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
Ngoài ra, nếu cần so sánh với một tham số để biết nên chọn phương án nào, bạn sẽ cần sử dụng bộ so sánh tích hợp sẵn thay vì kiểm tra giá trị:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const environment = params.defineString(‘ENVIRONMENT’, {default: 'dev'});
// use built-in comparators
const minInstancesConfig = environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
ENVIRONMENT = StringParam("ENVIRONMENT", default="dev")
MIN_INSTANCES = ENVIRONMENT.equals("PRODUCTION").then(10, 0)
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
Bạn có thể truy cập vào các tham số và biểu thức tham số chỉ được dùng trong thời gian chạy bằng hàm value:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE');
// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = onRequest(
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python
from firebase_functions import https_fn
from firebase_functions.params import StringParam
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
@https_fn.on_request()
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')
Tham số tích hợp sẵn
SDK Cloud Functions cung cấp 3 tham số được xác định trước, có trong gói con firebase-functions/params:
Node.js
projectID– dự án trên đám mây mà hàm đang chạy.databaseURL– URL của phiên bản Cơ sở dữ liệu theo thời gian thực được liên kết với hàm (nếu được bật trên dự án Firebase).storageBucket— bộ chứa Cloud Storage liên kết với hàm (nếu được bật trên dự án Firebase).
Python
PROJECT_ID– dự án trên đám mây mà hàm đang chạy.DATABASE_URL– URL của phiên bản Cơ sở dữ liệu theo thời gian thực được liên kết với hàm (nếu được bật trên dự án Firebase).STORAGE_BUCKET— bộ chứa Cloud Storage liên kết với hàm (nếu được bật trên dự án Firebase).
Các hàm này giống như các tham số chuỗi do người dùng xác định về mọi mặt, ngoại trừ việc vì Giao diện dòng lệnh (CLI) của Firebase luôn biết giá trị của các hàm này, nên các giá trị này sẽ không bao giờ được nhắc khi triển khai cũng như không được lưu vào tệp .env.
Tham số bí mật
Các tham số thuộc loại Secret, được xác định bằng defineSecret(), đại diện cho các tham số chuỗi có giá trị được lưu trữ trong Trình quản lý bí mật trên đám mây. Thay vì kiểm tra tệp .env cục bộ và ghi một giá trị mới vào tệp nếu thiếu, các tham số bí mật sẽ kiểm tra xem có tồn tại trong Trình quản lý bí mật trên đám mây hay không và nhắc nhập giá trị của một khoá bí mật mới trong quá trình triển khai.
Các tham số bí mật phải được liên kết với từng hàm có quyền truy cập vào các tham số đó:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');
export const postToDiscord = onRequest(
{ secrets: [discordApiKey] },
(req, res) => {
const apiKey = discordApiKey.value();
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import SecretParam
DISCORD_API_KEY = SecretParam('DISCORD_API_KEY')
@https_fn.on_request(secrets=[DISCORD_API_KEY])
def post_to_discord(req):
api_key = DISCORD_API_KEY.value
Vì giá trị của khoá bí mật bị ẩn cho đến khi hàm được thực thi, nên bạn không thể sử dụng các giá trị đó trong khi định cấu hình hàm.
Thông tin mật JSON có cấu trúc
Nếu có nhiều giá trị cấu hình liên quan đến nhau về mặt logic (ví dụ: chế độ cài đặt cho dịch vụ bên thứ ba), bạn có thể lưu trữ các giá trị đó cùng nhau dưới dạng một đối tượng JSON có cấu trúc trong một khoá bí mật duy nhất bằng cách sử dụng defineJsonSecret(). Phương pháp này có thể giúp sắp xếp cấu hình và sử dụng hiệu quả hơn cấp miễn phí của Cloud Secret Manager bằng cách lưu trữ một nhóm giá trị cấu hình có liên quan trong một khoá bí mật.
Giá trị được lưu trữ trong Trình quản lý bí mật phải là một chuỗi JSON hợp lệ. SDK sẽ tự động phân tích cú pháp chuỗi JSON thành một đối tượng JavaScript khi bạn truy cập vào .value().
Ví dụ:
const { onRequest } = require('firebase-functions/v2/https');
const { defineJsonSecret } = require('firebase-functions/params');
// Define a single secret to hold all configuration for some API
const someApiConfig = defineJsonSecret('SOMEAPI_CONFIG');
exports.myApi = onRequest(
{ secrets: [someApiConfig] },
(req, res) => {
// someApiConfig.value() automatically parses the JSON secret
const { apiKey, webhookSecret, clientId } = someApiConfig.value();
// Now you can use apiKey, webhookSecret, clientId
// ...
}
);
Để tạo khoá bí mật SOMEAPI_CONFIG, bạn cần đặt giá trị của khoá đó trong Trình quản lý bí mật thành một chuỗi JSON như sau:
{
"apiKey": "key_...",
"webhookSecret": "secret_...",
"clientId": "client_..."
}
Nếu giá trị bí mật không phải là JSON hợp lệ, thì việc truy cập vào someApiConfig.value() sẽ gửi một lỗi trong thời gian chạy.
Biến môi trường
Cloud Functions for Firebase hỗ trợ định dạng tệp dotenv để tải các biến môi trường được chỉ định trong tệp .env vào thời gian chạy của ứng dụng. Sau khi triển khai, bạn có thể đọc các biến môi trường thông qua giao diện process.env (trong các dự án dựa trên Node.js) hoặc os.environ (trong các dự án dựa trên Python).
Để định cấu hình môi trường theo cách này, hãy tạo một tệp .env trong dự án, thêm các biến mong muốn rồi triển khai:
Tạo tệp
.envtrong thư mụcfunctions/:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.jsMở tệp
.envđể chỉnh sửa và thêm các khoá mong muốn. Ví dụ:PLANET=Earth AUDIENCE=HumansTriển khai các hàm và xác minh rằng các biến môi trường đã được tải:
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
Sau khi triển khai các biến môi trường tuỳ chỉnh, mã hàm của bạn có thể truy cập vào các biến đó:
Node.js
// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
Python
import os
@https_fn.on_request()
def hello(req):
return https_fn.Response(
f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
)
Triển khai nhiều nhóm biến môi trường
Nếu bạn cần một tập hợp biến môi trường thay thế cho các dự án Firebase (chẳng hạn như thử nghiệm so với chính thức), hãy tạo tệp .env.<project or
alias> và viết các biến môi trường dành riêng cho dự án vào đó. Các biến môi trường trong tệp .env và tệp .env dành riêng cho dự án (nếu có) sẽ được đưa vào tất cả các hàm đã triển khai.
Ví dụ: một dự án có thể bao gồm 3 tệp này chứa các giá trị hơi khác nhau cho quá trình phát triển và phát hành công khai:
.env
|
.env.dev
|
.env.prod
|
| PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Prod Humans |
Dựa trên các giá trị trong những tệp riêng biệt đó, tập hợp biến môi trường được triển khai cùng với các hàm của bạn sẽ khác nhau tuỳ thuộc vào dự án mục tiêu:
$ firebase use dev
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.dev.
# Deploys functions with following user-defined environment variables:
# PLANET=Earth
# AUDIENCE=Dev Humans
$ firebase use prod
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.prod.
# Deploys functions with following user-defined environment variables:
# PLANET=Earth
# AUDIENCE=Prod Humans
Biến môi trường dành riêng
Một số khoá biến môi trường được dành riêng cho mục đích sử dụng nội bộ. Không sử dụng bất kỳ khoá nào trong số này trong tệp .env:
- Tất cả khoá bắt đầu bằng X_GOOGLE_
- Tất cả khoá bắt đầu bằng EXT_
- Tất cả khoá bắt đầu bằng FIREBASE_
- Bất kỳ khoá nào trong danh sách sau:
- CLOUD_RUNTIME_CONFIG
- ENTRY_POINT
- GCP_PROJECT
- GCLOUD_PROJECT
- GOOGLE_CLOUD_PROJECT
- FUNCTION_TRIGGER_TYPE
- FUNCTION_NAME
- FUNCTION_MEMORY_MB
- FUNCTION_TIMEOUT_SEC
- FUNCTION_IDENTITY
- FUNCTION_REGION
- FUNCTION_TARGET
- FUNCTION_SIGNATURE_TYPE
- K_SERVICE
- K_REVISION
- CỔNG
- K_CONFIGURATION
Lưu trữ và truy cập thông tin cấu hình nhạy cảm
Bạn có thể sử dụng các biến môi trường được lưu trữ trong tệp .env để định cấu hình hàm, nhưng không nên coi đây là cách an toàn để lưu trữ thông tin nhạy cảm, chẳng hạn như thông tin đăng nhập cơ sở dữ liệu hoặc khoá API. Điều này đặc biệt quan trọng nếu bạn kiểm tra các tệp .env trong chế độ kiểm soát nguồn.
Để giúp bạn lưu trữ thông tin cấu hình nhạy cảm, Cloud Functions for Firebase tích hợp với Google Cloud Secret Manager. Dịch vụ đã mã hoá này lưu trữ các giá trị cấu hình một cách an toàn, đồng thời vẫn cho phép bạn dễ dàng truy cập từ các hàm khi cần.
Tạo và sử dụng mật khẩu
Để tạo một khoá bí mật, hãy sử dụng CLI Firebase.
Cách tạo và sử dụng khoá bí mật:
Trong thư mục gốc của thư mục dự án cục bộ, hãy chạy lệnh sau:
firebase functions:secrets:set SECRET_NAME
Nhập một giá trị cho SECRET_NAME.
CLI sẽ lặp lại thông báo thành công và cảnh báo rằng bạn phải triển khai các hàm để thay đổi có hiệu lực.
Trước khi triển khai, hãy đảm bảo mã hàm cho phép hàm truy cập vào khoá bí mật bằng tuỳ chọn
secrets:Node.js
const { onRequest } = require('firebase-functions/v2/https'); exports.processPayment = onRequest( { secrets: ["SECRET_NAME"] }, (req, res) => { const myBillingService = initializeBillingService( // reference the secret value process.env.SECRET_NAME ); // Process the payment } );Python
import os from firebase_functions import https_fn @https_fn.on_request(secrets=["SECRET_NAME"]) def process_payment(req): myBillingService = initialize_billing(key=os.environ.get('SECRET_NAME')) # Process the payment ...Triển khai Cloud Functions:
firebase deploy --only functions
Giờ đây, bạn có thể truy cập vào biến này như mọi biến môi trường khác. Ngược lại, nếu một hàm khác không chỉ định khoá bí mật cố gắng truy cập vào khoá bí mật, thì hàm đó sẽ nhận được một giá trị không xác định:
Node.js
exports.anotherEndpoint = onRequest((request, response) => { response.send(`The secret API key is ${process.env.SECRET_NAME}`); // responds with "The secret API key is undefined" because the `secrets` option is missing });Python
@https_fn.on_request() def another_endpoint(req): return https_fn.Response(f"The secret API key is {os.environ.get("SECRET_NAME")}") # Responds with "The secret API key is None" because the `secrets` parameter is missing.
Sau khi được triển khai, hàm của bạn sẽ có quyền truy cập vào giá trị bí mật. Chỉ những hàm có chứa khoá bí mật trong tuỳ chọn secrets mới có quyền truy cập vào khoá bí mật đó dưới dạng biến môi trường. Điều này giúp đảm bảo rằng các giá trị bí mật chỉ có sẵn ở những nơi cần thiết, giảm nguy cơ vô tình làm rò rỉ thông tin bí mật.
Quản lý thông tin bí mật
Sử dụng CLI Firebase để quản lý thông tin mật. Trong khi quản lý bí mật theo cách này, hãy lưu ý rằng một số thay đổi về CLI yêu cầu bạn sửa đổi và/hoặc triển khai lại các hàm liên quan. Cụ thể:
- Bất cứ khi nào đặt giá trị mới cho một khoá bí mật, bạn phải triển khai lại tất cả hàm tham chiếu đến khoá bí mật đó để các hàm này nhận được giá trị mới nhất.
- Nếu bạn xoá một khoá bí mật, hãy đảm bảo rằng không có hàm nào đã triển khai tham chiếu đến khoá bí mật đó. Các hàm sử dụng giá trị bí mật đã bị xoá sẽ không hoạt động mà không có thông báo.
Sau đây là thông tin tóm tắt về các lệnh CLI Firebase để quản lý bí mật:
# Change the value of an existing secret firebase functions:secrets:set SECRET_NAME # Set secret from file firebase functions:secrets:set SECRET_NAME --data-file file.json # Validate secret value as json cat file.json | firebase functions:secrets:set SECRET_NAME --format=json # Pipe from stdin and set secret cat file.json | firebase functions:secrets:set SECRET_NAME --format=json # View the value of a secret functions:secrets:access SECRET_NAME # Destroy a secret functions:secrets:destroy SECRET_NAME # View all secret versions and their state functions:secrets:get SECRET_NAME # Automatically clean up all secrets that aren't referenced by any of your functions functions:secrets:prune
Đối với các lệnh access và destroy, bạn có thể cung cấp tham số phiên bản không bắt buộc để quản lý một phiên bản cụ thể. Ví dụ:
functions:secrets:access SECRET_NAME[@VERSION]
Để biết thêm thông tin về các thao tác này, hãy truyền -h bằng lệnh để xem phần trợ giúp về CLI.
Cách tính phí cho mật khẩu
Secret Manager cho phép 6 phiên bản mật mã đang hoạt động mà không mất phí. Điều này có nghĩa là bạn có thể có 6 khoá bí mật mỗi tháng trong một dự án Firebase mà không tốn phí.
Theo mặc định, CLI Firebase sẽ cố gắng tự động huỷ các phiên bản bí mật không dùng đến khi thích hợp, chẳng hạn như khi bạn triển khai các hàm có phiên bản bí mật mới. Ngoài ra, bạn có thể chủ động dọn dẹp các khoá bí mật không dùng đến bằng cách sử dụng functions:secrets:destroy và functions:secrets:prune.
Secret Manager cho phép 10.000 thao tác truy cập hằng tháng không tính phí đối với một mật khẩu. Mỗi khi khởi động nguội, các thực thể hàm chỉ đọc những khoá bí mật được chỉ định trong tuỳ chọn secrets. Nếu bạn có nhiều thực thể hàm
đọc nhiều khoá bí mật, thì dự án của bạn có thể vượt quá mức cho phép này. Khi đó, bạn sẽ bị tính phí 0,03 USD cho mỗi 10.000 thao tác truy cập.
Để biết thêm thông tin, hãy xem phần Giá của Secret Manager.
Hỗ trợ trình mô phỏng
Cấu hình môi trường bằng dotenv được thiết kế để tương tác với trình mô phỏng Cloud Functions cục bộ.
Khi sử dụng trình mô phỏng Cloud Functions cục bộ, bạn có thể ghi đè các biến môi trường cho dự án bằng cách thiết lập tệp .env.local. Nội dung của .env.local được ưu tiên hơn .env và tệp .env dành riêng cho dự án.
Ví dụ: một dự án có thể bao gồm 3 tệp này chứa các giá trị hơi khác nhau cho quá trình phát triển và kiểm thử cục bộ:
.env
|
.env.dev
|
.env.local
|
| PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Local Humans |
Khi được khởi động trong bối cảnh địa phương, trình mô phỏng sẽ tải các biến môi trường như sau:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Thông tin bí mật và thông tin đăng nhập trong trình mô phỏng Cloud Functions
Trình mô phỏng Cloud Functions hỗ trợ việc sử dụng khoá bí mật để lưu trữ và truy cập thông tin cấu hình nhạy cảm. Theo mặc định, trình mô phỏng sẽ cố gắng truy cập vào các bí mật trong môi trường thực tế bằng cách sử dụng thông tin xác thực mặc định của ứng dụng. Trong một số trường hợp nhất định như môi trường CI, trình mô phỏng có thể không truy cập được vào các giá trị bí mật do các quy định hạn chế về quyền.
Tương tự như tính năng hỗ trợ của trình mô phỏng Cloud Functions cho các biến môi trường, bạn có thể ghi đè các giá trị bí mật bằng cách thiết lập tệp .secret.local. Điều này giúp bạn dễ dàng kiểm thử các hàm trên máy, đặc biệt là khi bạn không có quyền truy cập vào giá trị bí mật.
Di chuyển từ cấu hình thời gian chạy
API functions.config không còn được dùng nữa và sẽ ngừng hoạt động vào tháng 3 năm 2027.
Sau ngày đó, các hoạt động triển khai có functions.config sẽ không thành công.
Để tránh lỗi triển khai, hãy di chuyển cấu hình của bạn sang Cloud Secret Manager bằng CLI Firebase. Bạn nên sử dụng cách này vì đây là cách hiệu quả và an toàn nhất để di chuyển cấu hình.
Xuất cấu hình bằng CLI Firebase
Sử dụng lệnh
config exportđể xuất cấu hình môi trường hiện có sang một khoá bí mật mới trong Cloud Secret Manager:$ firebase functions:config:export i This command retrieves your Runtime Config values (accessed via functions.config()) and exports them as a Secret Manager secret. i Fetching your existing functions.config() from your project... ✔ Fetched your existing functions.config(). i Configuration to be exported: ⚠ This may contain sensitive data. Do not share this output. { ... } ✔ What would you like to name the new secret for your configuration? RUNTIME_CONFIG ✔ Created new secret version projects/project/secrets/RUNTIME_CONFIG/versions/1```Cập nhật mã hàm để liên kết khoá bí mật
Để sử dụng cấu hình được lưu trữ trong khoá bí mật mới trong Cloud Secret Manager, hãy sử dụng API
defineJsonSecrettrong nguồn hàm của bạn. Ngoài ra, hãy đảm bảo rằng các khoá bí mật được liên kết với tất cả các hàm cần đến chúng.Trước
const functions = require("firebase-functions/v1"); exports.myFunction = functions.https.onRequest((req, res) => { const apiKey = functions.config().someapi.key; // ... });Sau
const { onRequest } = require("firebase-functions/v2/https"); const { defineJsonSecret } = require("firebase-functions/params"); const config = defineJsonSecret("RUNTIME_CONFIG"); exports.myFunction = onRequest( // Bind secret to your function { secrets: [config] }, (req, res) => { // Access secret values via .value() const apiKey = config.value().someapi.key; // ... });Triển khai hàm
Triển khai các hàm đã cập nhật để áp dụng các thay đổi và liên kết các quyền truy cập bí mật.
firebase deploy --only functions:<your-function-name>
Biến môi trường được điền tự động
Có các biến môi trường được tự động điền trong thời gian chạy của hàm và trong các hàm được mô phỏng cục bộ. Các biến này bao gồm những biến được điền sẵn bằng Google Cloud, cũng như một biến môi trường dành riêng cho Firebase:
process.env.FIREBASE_CONFIG: Cung cấp thông tin cấu hình dự án Firebase sau đây:
{
databaseURL: 'https://DATABASE_NAME.firebaseio.com',
storageBucket: 'PROJECT_ID.firebasestorage.app ',
projectId: 'PROJECT_ID'
}
Xin lưu ý rằng các giá trị trong cấu hình Firebase thực tế của bạn có thể thay đổi tuỳ thuộc vào tài nguyên bạn đã cung cấp trong dự án.
Cấu hình này được áp dụng tự động khi bạn khởi động SDK của Firebase dành cho quản trị viên mà không có đối số. Nếu bạn đang viết hàm bằng JavaScript, hãy khởi chạy như sau:
const admin = require('firebase-admin');
admin.initializeApp();
Nếu bạn đang viết hàm bằng TypeScript, hãy khởi chạy như sau:
import * as functions from 'firebase-functions/v1';
import * as admin from 'firebase-admin';
import 'firebase-functions/v1';
admin.initializeApp();
Nếu cần khởi chạy SDK quản trị bằng cấu hình dự án mặc định bằng thông tin đăng nhập của tài khoản dịch vụ, bạn có thể tải thông tin đăng nhập từ một tệp và thêm thông tin đăng nhập đó vào FIREBASE_CONFIG như sau:
serviceAccount = require('./serviceAccount.json');
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);