Thông thường, bạn sẽ cần định cấu hình bổ sung cho các hàm của mình, chẳng hạn như khoá API của bên thứ ba hoặc các chế độ cài đặt có thể điều chỉnh. SDK Firebase cho Cloud Functions cung cấp cấu hình môi trường tích hợp để 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 một trong các lựa chọn sau:
- Cấu hình tham số (nên dùng cho hầu hết các trường hợp). Cấu hình này cung cấp cấu hình môi trường được nhập mạnh mẽ 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á quá trình 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ự tạo tệp dotenv để 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 tham số. Phương pháp này giúp 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ả các tham số đều có giá trị hợp lệ. Ngược lại, cấu hình với các biến môi trường không có sẵn tại thời điểm triển khai.
Cấu hình 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 một 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 quá trình triển khai trừ phi tất cả cá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 tham số, Firebase CLI sẽ cố gắng tải các giá trị của chúng từ các tệp .env cục bộ. Nếu các giá trị này
không có trong các tệp đó và không có default nào được thiết lập, thì CLI sẽ nhắc bạn 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 của bạn, bạn có thể thêm tệp .env.<project_ID> đã tạo vào tính năng quản lý phiên bản.
Sử dụng các tham số trong phạm vi toàn cục
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. Điều này có nghĩa là việc tìm nạp các 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ị toàn cục, 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 một 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ó trong quá trình xử lý các hàm đã liên kết bí mật. Nếu một 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ị sai 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 đối tượng Options để kiểm soát cách CLI sẽ nhắc bạn nhập các giá trị. Ví dụ sau đây thiết lập 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 tham số cung cấp tính năng nhập mạnh mẽ cho các giá trị tham số, đồng thời hỗ trợ các bí mật từ Cloud Secret Manager. 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 tài liệu tham khảo về không gian tên params
để biết thông tin về các hàm dùng để xác định tham số.
Giá trị và biểu thức tham số
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ác môi trường kép này, bạn phải cẩn thận hơn khi so sánh các giá trị tham số và khi sử dụng các giá trị này để thiết lập các tuỳ chọn thời gian chạy cho các hàm của mình.
Để truyền một tham số vào hàm của bạn 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 bạn cần so sánh với một tham số để biết nên chọn tuỳ chọn nào, bạn sẽ cần sử dụng bộ so sánh tích hợp 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 các tham số và biểu thức tham số chỉ được sử dụng trong thời gian chạy bằng hàm value của chúng:
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!')
Các tham số tích hợp
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 trong đó.databaseURL– URL của thực thể 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– vùng chứa Cloud Storage được 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 trong đó.DATABASE_URL– URL của thực thể 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– vùng chứa Cloud Storage được 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ì các giá trị của chúng luôn được Firebase CLI biết, nên các giá trị này sẽ không bao giờ được nhắc nhập khi triển khai cũng như không được lưu vào các 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 Cloud Secret Manager. Thay vì kiểm tra tệp .env cục bộ và ghi giá trị mới vào tệp nếu bị thiếu, các tham số bí mật sẽ kiểm tra sự tồn tại trong Cloud Secret Manager và nhắc bạn nhập giá trị của một 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 các hàm riêng lẻ cần 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ì các giá trị của bí mật bị ẩn cho đến khi thực thi hàm, nên bạn không thể sử dụng các giá trị này trong khi định cấu hình hàm.
Bí mật JSON có cấu trúc
Nếu có nhiều giá trị cấu hình liên quan một cách logic (ví dụ: chế độ cài đặt cho dịch vụ của bên thứ ba), bạn có thể lưu trữ các giá trị này cùng nhau dưới dạng đối tượng JSON có cấu trúc trong một bí mậ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 của bạn và sử dụng hiệu quả hơn bậc miễn phí của Cloud Secret Manager bằng cách lưu trữ một nhóm các giá trị cấu hình liên quan trong một bí mật.
Giá trị được lưu trữ trong Secret Manager 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 đố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 bí mật SOMEAPI_CONFIG, bạn sẽ đặt giá trị của bí mật đó trong Secret Manager thành một chuỗi JSON như:
{
"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ây ra 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 ứng dụng của bạn. 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 của bạn theo cách này, hãy tạo tệp .env trong dự án của bạn, thêm các biến mong muốn và 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 các biến môi trường tuỳ chỉnh của bạn được triển khai, 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 tập hợp 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
của mình (chẳng hạn như dàn dựng so với sản xuất), hãy tạo tệp
.env.<project or
alias> và ghi các biến môi trường dành riêng cho
dự án của bạn vào đó. Các biến môi trường từ 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à sản xuất:
.env
|
.env.dev
|
.env.prod
|
| PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Prod Humans |
Với các giá trị trong các tệp riêng biệt đó, tập hợp các biến môi trường được triển khai 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 của bạn:
$ 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
Các 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 các tệp .env của bạn:
- Tất cả các khoá bắt đầu bằng X_GOOGLE_
- Tất cả các khoá bắt đầu bằng EXT_
- Tất cả cá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
- PORT
- 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 các tệp .env để định cấu hình hàm, nhưng bạn không nên coi các biến này là cách an toàn để lưu trữ thông tin nhạy cảm 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 của mình vào tính năng 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ụ được 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 dễ dàng truy cập từ các hàm của bạn khi cần.
Tạo và sử dụng bí mật
Để tạo bí mật, hãy sử dụng Firebase CLI.
Cách tạo và sử dụng bí mật:
Từ 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 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 rằng mã hàm của bạn cho phép hàm truy cập vào bí mật bằng cách sử dụ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 giống như bất kỳ biến môi trường nào khác. Ngược lại, nếu một hàm khác không chỉ định bí mật cố gắng truy cập vào bí mật, thì hàm đó sẽ nhận được 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 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ụ thể bao gồm một bí mật trong tuỳ chọn secrets mới có quyền truy cập vào bí mật đó dưới dạng biến môi trường. Điều này giúp bạn đả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ỉ bí mật.
Quản lý bí mật
Sử dụng Firebase CLI để quản lý bí mật của bạn. Trong khi quản lý bí mật theo cách này, hãy lưu ý rằng một số thay đổi của CLI yêu cầu bạn phải sửa đổi và/hoặc triển khai lại các hàm được liên kết. Cụ thể:
- Bất cứ khi nào bạn đặt giá trị mới cho một bí mật, bạn phải triển khai lại tất cả các hàm tham chiếu đến bí mật đó để các hàm này nhận giá trị mới nhất.
- Nếu bạn xoá một bí mật, hãy đảm bảo rằng không có hàm nào đã triển khai tham chiếu đến bí mật đó. Các hàm sử dụng giá trị bí mật đã bị xoá sẽ không thành công.
Sau đây là tóm tắt các lệnh Firebase CLI để 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 của CLI.
Cách tính phí bí mật
Secret Manager cho phép 6 phiên bản bí mật đang hoạt động mà không tốn phí. Điều này có nghĩa là bạn có thể có 6 bí mật mỗi tháng trong một dự án Firebase mà không tốn phí.
Theo mặc định, Firebase CLI sẽ cố gắng tự động hủy bỏ 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 Functions 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 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 chưa tính phí trên một
bí mật. Các thực thể hàm chỉ đọc các bí mật được chỉ định trong tuỳ chọn secrets mỗi khi chúng khởi động nguội. Nếu bạn có nhiều thực thể hàm đọc nhiều bí mật, dự án của bạn có thể vượt quá hạn mức này. Tại thời điểm đó, 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 Secret Manager Bảng giá.
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 a 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 của mình bằng cách thiết lập tệp .env.local Nội dung của
.env.local sẽ đượ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à thử nghiệm 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 cục bộ, 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
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 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 sản xuất của bạn bằng cách sử dụng thông tin đăng nhập mặc định của ứng dụng. Trong một số trường hợp 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 hạn chế về quyền.
Tương tự như tính năng hỗ trợ 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 của mình trên máy, đặc biệt nếu 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 đã ngừng hoạt động và sẽ ngừng hoạt động vào tháng 3 năm 2027.
Sau ngày đó, các lượt triển khai bằng functions.config sẽ không thành công.
Để ngăn lỗi triển khai, hãy di chuyển cấu hình của bạn sang Cloud Secret Manager bằng Firebase CLI. Bạn nên thực hiện việc này vì đây là cách hiệu quả và an toàn nhất để di chuyển cấu hình của bạn.
Xuất cấu hình bằng Firebase CLI
Sử dụng lệnh
config exportđể xuất cấu hình môi trường hiện có sang một 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 các bí mật
Để sử dụng cấu hình được lưu trữ trong 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 bí mật được liên kết với tất cả các hàm cần đến các bí mật đó.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 các 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 bí mật.
firebase deploy --only functions:<your-function-name>
Các biến môi trường được tự động điền
Có các biến môi trường được tự động điền trong thời gian chạy hàm và trong các hàm được mô phỏng cục bộ. Các biến này bao gồm các biến được Google Cloudđiền, cũng như 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ể khác nhau tuỳ thuộc vào các tài nguyên mà bạn đã cung cấp trong dự án của mình.
Cấu hình này được tự động áp dụng khi bạn khởi chạy SDK quản trị Firebase mà không có đối số. Nếu bạn đang viết các 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 các 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 bạn cần khởi động SDK dành cho quản trị viên bằng cấu hình dự án mặc định bằng cách sử dụng thông tin đăng nhập 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);