您可以使用 Firebase CLI 命令或在函数源代码中设置运行时选项来部署、删除和修改函数。
部署函数
如需部署函数,请运行此 Firebase CLI 命令:
firebase deploy --only functions
默认情况下,Firebase CLI 会同时部署 index.js
内的所有函数。如果您的项目包含 5 个以上的函数,建议您使用 --only
标志并指定函数名称,以便仅部署您已修改的函数。以这种方式部署特定函数可加快部署流程,并有助于避免达到部署配额。例如:
firebase deploy --only functions:addMessage,functions:makeUppercase
部署大量函数时,可能会超出标准配额,并收到 HTTP 429 或 500 错误消息。如需解决此问题,请以 10 或更少数量为单位分批部署函数。
如需查看可用命令的完整列表,请参阅 Firebase CLI 参考文档。
默认情况下,Firebase CLI 会在 functions/
文件夹中查找源代码。您可以在 firebase.json
中添加以下行来指定另一文件夹:
"functions": {
"source": "another-folder"
}
删除函数
您可以通过以下方式删除以前部署的函数:
- 在 Firebase CLI 中使用
functions:delete
显式删除 - 在 Firebase 控制台中使用函数列表中的上下文菜单显式删除
- 在部署前通过从
index.js
中移除函数隐式删除。
所有删除操作都会提示您确认是否从生产环境中移除函数。
Firebase CLI 中的显式函数删除操作支持多个参数以及函数组,并允许您指定在特定区域中运行的函数。 此外,您还可以覆盖确认提示。
# Delete all functions that match the specified name in all regions. firebase functions:delete myFunction
# Delete a specified function running in a specific region. firebase functions:delete myFunction --region us-east-1
# Delete more than one function firebase functions:delete myFunction myOtherFunction
# Delete a specified functions group. firebase functions:delete groupA
# Bypass the confirmation prompt. firebase functions:delete myFunction --force
对于隐式函数删除,firebase deploy
会解析 index.js
并从生产环境中移除已从文件中移除的任何函数。
修改函数的名称、区域或触发器
如需更改正在处理生产流量的函数的名称、区域或触发器,请按本部分中的步骤操作,以避免在修改期间丢失事件。在执行这些步骤之前,请先确保您的函数为幂等函数,因为在更改期间,函数的新版本和旧版本均会处于运行状态。
重命名函数
如需重命名函数,请在 index.js
中创建函数改名后的新版本,然后分别运行两个部署命令。第一个命令部署改名后的函数,而第二个命令则移除以前部署的版本。例如,如果您要将名为 webhook
的函数更名为 webhookNew
,请按以下方式修改代码:
// before
const functions = require('firebase-functions');
exports.webhook = functions.https.onRequest((req, res) => {
res.send("Hello");
});
// after
const functions = require('firebase-functions');
exports.webhookNew = functions.https.onRequest((req, res) => {
res.send("Hello");
});
然后运行以下命令,部署新函数:
# Deploy new function called webhookNew firebase deploy --only functions:webhookNew # Wait until deployment is done; now both webhookNew and webhook are running # Delete webhook firebase functions:delete webhook
更改函数的一个或多个区域
如需更改正在处理生产流量的函数的指定区域,您可以按顺序执行以下步骤,以防止丢失事件:
- 重命名该函数,并根据需要更改其一个或多个区域。
- 部署重命名的函数,这样就会暂时在两组区域中运行相同的代码。
- 删除先前的函数。
例如,如果您有一个名为 webhook
的函数当前位于 us-central1
的默认函数区域,您希望将其迁移到 asia-northeast1
,则需要先修改源代码,重命名该函数并修改区域。
// before
const functions = require('firebase-functions');
exports.webhook = functions
.https.onRequest((req, res) => {
res.send("Hello");
});
// after
const functions = require('firebase-functions');
exports.webhookAsia = functions
.region('asia-northeast1')
.https.onRequest((req, res) => {
res.send("Hello");
});
然后运行以下命令部署函数:
firebase deploy --only functions:webhookAsia
现在有两个相同的函数在运行:webhook
在 us-central1
中运行,webhookAsia
在 asia-northeast1
中运行。
然后,删除 webhook
:
firebase functions:delete webhook
现在只有一个函数 webhookAsia
,它在 asia-northeast1
中运行。
更改函数的触发器类型
当您的 Cloud Functions for Firebase 部署工作开展一段时间后,您可能会出于各种原因而需要更改函数的触发器类型。例如,您可能希望:
- 从旧版存储
onChange
事件更改为onFinalize
、onDelete
、onArchive
和onMetadataUpdate
。(如需了解这方面的详情,请参阅 Beta 版到 v1 或 v2 的升级指南)。 - 更改 Firebase Realtime Database 或 Cloud Firestore 事件的类型,例如,将宽泛的
onWrite
事件更改为细化的onCreate
事件。
仅凭更改源代码和运行 firebase deploy
无法更改函数的事件类型。为避免错误,请按以下程序更改函数的触发器类型:
- 修改源代码,加入具备所需触发器类型的新函数。
- 部署该函数,这样暂时会同时运行新旧两个函数。
- 利用 Firebase CLI 从生产环境中以显式方法删除旧函数。
例如,如果您有一个函数 objectChanged
具有旧版 onChange
事件类型,而您希望将其更改为 onFinalize
,请先重命名该函数,再将其事件类型修改为 onFinalize
。
// before
const functions = require('firebase-functions');
exports.objectChanged = functions.storage.object().onChange((object) => {
return console.log('File name is: ', object.name);
});
// after
const functions = require('firebase-functions');
exports.objectFinalized = functions.storage.object().onFinalize((object) => {
return console.log('File name is: ', object.name);
});
然后运行以下命令,以便先创建新函数,然后再删除旧函数:
# Create new function objectFinalized firebase deploy --only functions:objectFinalized # Wait until deployment is done; now both objectChanged and objectFinalized are running # Delete objectChanged firebase functions:delete objectChanged
设置运行时选项
Cloud Functions for Firebase 允许用户选择运行时选项,例如 Node.js 运行时版本、各函数的超时时间、内存分配以及函数实例数量上下限。
设置 Node.js 版本
Firebase SDK for Cloud Functions 2.0.0 及更高版本支持选择 Node.js 运行时。 您可以选择仅在下面其中一个受支持的 Node.js 版本所对应的运行时环境中运行一个项目中的所有函数:
- Node.js 16
- Node.js 14
- Node.js 12
- Node.js 10
- Node.js 8(从 2020 年 6 月 8 日起弃用) 自 2020 年 12 月 15 日起,您已无法在 Firebase CLI 中将函数部署到 Node.js 8 运行时。已部署的函数会在将来某个时刻停止执行;如果您已将函数部署到 Node.js 8 运行时,我们建议您升级到 Node.js 16 运行时。
如需设置 Node.js 版本,请执行以下操作:
在初始化期间在 functions/
目录中创建的 package.json
文件的 engines
字段中设置版本。
例如,如仅需使用版本 16,请在 package.json
中修改此行:
"engines": {"node": "16"}
engines
是必填字段;必须通过该字段指定一个受支持的 Node.js 版本,以便您部署和运行函数。目前,firebase init functions
将此字段设置为 16
。
升级 Node.js 运行时
如需升级 Node.js 运行时,请执行以下操作:
- 确保您的项目采用的是 Blaze 定价方案。
- 确保您使用的是 Firebase CLI v9.17.0 或更高版本。
- 在初始化期间更改在
functions/
目录中创建的package.json
文件中的engines
值。例如,如果您要从版本 10 升级到版本 16,请按下方所示设置该字段:"engines": {"node": "16"}
- (可选)使用 Firebase Local Emulator Suite 测试您的更改。
- 使用 Firebase CLI v9.17.0 或更高版本重新部署函数。
控制扩缩行为
默认情况下,Cloud Functions for Firebase 会根据传入请求数量扩缩运行的实例数量,当流量减少时可能会将实例数缩减为零。但是,如果您的应用要求更低的延迟时间,并且您希望限制冷启动次数,您可以指定保持备用状态并已准备好处理请求的容器实例数下限,来更改此默认行为。
同样,您也可以设置数量上限,限制为应对传入请求而扩增的实例数。使用此设置可以控制您的费用或限制与备份服务(如数据库)的连接数。
减少冷启动次数
如需在源代码中为函数设置实例数下限,请使用 runWith
参数。此运行时选项接受符合 RuntimeOptions
接口的 JSON 对象(定义 minInstances
的值)。例如,此函数将保持备用状态的实例数下限设置为 5:
exports.getAutocompleteResponse = functions
.runWith({
// Keep 5 instances warm for this latency-critical function
minInstances: 5,
})
.https.onCall((data, context) => {
// Autocomplete a user's search term
});
为 minInstances
设置值时,您需要考虑以下事项:
- 如果 Cloud Functions for Firebase 将您的应用扩容到超过
minInstances
设置范围,超出该阈值以后的每个实例都会进行冷启动。 - 冷启动对于有流量激增现象的应用的影响很严重。如果您的应用流量会激增,并且您将
minInstances
值设置得足够高,可以在每次流量增加时减少冷启动次数,现延迟时间将明显缩短。对于流量稳定的应用,冷启动不太可能严重影响性能。 设置实例数下限可能适合生产环境,但在测试环境中通常应避免。如需在测试项目中缩减至零,但仍在生产项目中减少冷启动,您可以根据
FIREBASE_CONFIG
环境变量设置minInstances
:// Get Firebase project id from `FIREBASE_CONFIG` environment variable const envProjectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId; exports.renderProfilePage = functions .runWith({ // Keep 5 instances warm for this latency-critical function // in production only. Default to 0 for test projects. minInstances: envProjectId === "my-production-project" ? 5 : 0, }) .https.onRequest((req, res) => { // render some html });
限制函数的实例数上限
如需在函数源代码中设置实例数上限,请使用 runWith
参数。此运行时选项接受符合 RuntimeOptions
接口的 JSON 对象(定义 maxInstances
的值)。例如,以下函数将实例数上限设置为 100,以避免假设的旧数据库超负荷:
exports.mirrorOrdersToLegacyDatabase = functions
.runWith({
// Legacy database only supports 100 simultaneous connections
maxInstances: 100,
})
.firestore.document("orders/{orderId}")
.onWrite((change, context) => {
// Connect to legacy database
});
如果 HTTP 函数扩容到 maxInstances
上限,则新请求将在队列中等候 30 秒;如果这段时间内仍没有可用的实例,则系统将拒绝此请求并返回响应代码 429 Too Many Requests
。
如需详细了解使用实例数上限设置的最佳做法,请查看这些使用 maxInstances
的最佳做法。
设置超时时间和内存分配
在某些情况下,您的函数可能有特殊要求,需要具备较长的超时值或分配较多的内存。您可以在 Google Cloud Console 或函数源代码(仅限 Firebase)中设置这些值。
如需在函数源代码中设置内存分配和超时,请使用 Firebase SDK for Cloud Functions 2.0.0 中引入的 runWith
参数。此运行时选项接受符合 RuntimeOptions
接口的 JSON 对象(定义 timeoutSeconds
和 memory
的值)。例如,以下存储函数使用 1GB 的内存,并会在 300 秒后超时:
exports.convertLargeFile = functions
.runWith({
// Ensure the function has enough memory and time
// to process large files
timeoutSeconds: 300,
memory: "1GB",
})
.storage.object()
.onFinalize((object) => {
// Do some complicated things that take a lot of memory and time
});
timeoutSeconds
的最大值为 540
或 9 分钟。
授予函数的内存量对应于为该函数分配的 CPU,详见下列 memory
的有效值列表:
128MB
- 200MHz256MB
- 400MHz512MB
- 800MHz1GB
- 1.4 GHz2GB
- 2.4 GHz4GB
- 4.8 GHz8GB
- 4.8 GHz
如需在 Google Cloud Console 中设置内存分配和超时,请执行以下操作:
- 在 Google Cloud Console 中,从左侧菜单中选择 Cloud Functions。
- 点击函数列表中的名称,选择相应函数。
- 点击顶部菜单中的修改图标。
- 从名为分配的内存的下拉菜单中选择内存分配。
- 点击更多以显示高级选项,并在超时文本框中输入秒数。
- 点击保存以更新函数。