您可以使用 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 CLI 中使用
functions:delete
- 明确地在谷歌云控制台中。
- 通过在部署之前从index.js中删除函数来
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 部署,您可能需要出于各种原因更改函数的触发器类型。例如,您可能希望将一种类型的 Firebase 实时数据库或 Cloud Firestore 事件更改为另一种类型,例如将通用的onWrite
事件更改为更精细的onCreate
事件。
仅通过更改源代码和运行firebase deploy
是不可能更改函数的事件类型的。为避免错误,请通过以下过程更改函数的触发器类型:
- 修改源代码以包含具有所需触发器类型的新函数。
- 部署函数,这会导致临时运行旧函数和新函数。
- 使用 Firebase CLI 从生产中明确删除旧函数。
例如,如果您有一个具有遗留onChange
事件类型的函数objectChanged
,并且您想要将其更改为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 版本除外)。此RuntimeOptions
对象是函数运行时选项的真实来源,并将覆盖通过任何其他方法(例如通过 Google Cloud 控制台或 gcloud CLI)设置的选项。
如果您的开发工作流程涉及通过 Google Cloud 控制台或 gcloud CLI 手动设置运行时选项,并且您不希望在每次部署时覆盖这些值,请将preserveExternalChanges
选项设置为true
。将此选项设置为true
后,Firebase 会将代码中设置的运行时选项与当前部署的函数版本的设置合并,优先级如下:
- 选项在功能代码中设置:覆盖外部更改。
- 选项在函数代码中设置为
RESET_VALUE
:使用默认值覆盖外部更改。 - 选项未在函数代码中设置,但在当前部署的函数中设置:使用已部署函数中指定的选项。
在大多数情况下,不建议使用preserveExternalChanges: true
选项,因为您的代码将不再是函数运行时选项的完整真实来源。如果确实要使用它,请检查 Google Cloud 控制台或使用 gcloud CLI 查看函数的完整配置。
设置 Node.js 版本
Firebase SDK for Cloud Functions 2.0.0 及更高版本允许选择 Node.js 运行时。您可以选择在与这些受支持的 Node.js 版本之一相对应的运行时环境中专门运行项目中的所有功能:
- 节点 18
- 节点 16
- 节点 14
设置 Node.js 版本:
在初始化期间在您的functions/
目录中创建的package.json
文件中的engines
字段中设置版本。例如,要仅使用版本 18,请在package.json
中编辑此行:
"engines": {"node": "18"}
engines
字段是必需的;它必须指定受支持的 Node.js 版本之一,以便您部署和运行功能。
升级您的 Node.js 运行时
要升级您的 Node.js 运行时:
- 确保您的项目在Blaze 定价计划中。
- 确保您使用的是 Firebase CLI v9.17.0 或更高版本。
- 更改初始化期间在
functions/
目录中创建的package.json
文件中的engines
值。例如,如果您要从版本 16 升级到版本 18,条目应如下所示:"engines": {"node": "18"}
- 或者,使用Firebase Local Emulator Suite测试您的更改。
- 使用 Firebase CLI v11.18.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
— 200MHz -
256MB
— 400MHz -
512MB
— 800MHz -
1GB
— 1.4 GHz -
2GB
— 2.4 GHz -
4GB
— 4.8 GHz -
8GB
— 4.8 GHz
要在 Google Cloud Console 中设置内存分配和超时:
- 在 Google Cloud Console 中,从左侧菜单中选择Cloud Functions 。
- 通过在函数列表中单击函数名称来选择函数。
- 单击顶部菜单中的编辑图标。
- 从标记为Memory allocated的下拉菜单中选择一个内存分配。
- 单击更多以显示高级选项,并在超时文本框中输入秒数。
- 单击保存以更新函数。