Firebase Cloud Functions 是一个服务器平台,用于在受管的 Node.js 环境中执行代码,能够响应 Firebase 事件、HTTPS 请求以及 Google 云服务中的变化。与传统后端不同,开发者无需配置服务器、安装 Web 服务器或担心扩展问题——每个函数都在隔离的容器中运行,并自动获得所需数量的资源。根据 Google Firebase(2026),该平台每天处理超过 20 亿次函数调用,为数百万移动应用提供无服务器架构。
要点
Firebase Cloud Functions 是一个基于 Google Cloud Functions(GCF)构建、并针对 Firebase 生态系统进行调整的计算平台。函数是普通的 JavaScript 或 TypeScript 代码,从模块导出并注册到特定的事件类型。当事件发生时(例如用户注册或上传文件),Firebase Cloud Functions 会运行相应的代码,并向其传递事件的上下文。
Cloud Functions 的架构遵循单一职责原则:一个函数处理一种类型的事件并执行一个原子操作。例如,sendWelcomeEmail 函数在 Firebase Authentication 中创建新用户时被调用,并发送欢迎邮件。这种隔离简化了在不同项目中调试、测试和复用函数。
每个函数都在具有临时生命周期的隔离容器中运行。最大执行时间默认为 60 秒(HTTPS 函数为 9 分钟)。如果函数未能在超时时间内完成,请求将以 500 错误结束。对于长时间运行的操作,请使用 Cloud Tasks 或带重试的 Pub/Sub。容器可以在后续调用中重复使用(keep-alive),从而减少首次调用后冷启动的延迟。
Firebase Cloud Functions 支持多个 Node.js 版本:18、20 和 22(新项目推荐使用)。版本选择在 package.json 文件的 engines 字段中设置。Firebase CLI 会根据指定的版本自动配置运行时环境。重要提示:Firebase Cloud Functions 不支持运行任意的 Docker 容器——运行环境由 Google Cloud Functions 严格固定。
对于新项目,推荐使用 Node.js 22,因为它包含最新的 V8 优化、改进的 ESM 模块支持以及平台级的 WebSocket 支持。如果项目使用了针对特定 Node 版本编译的依赖项(例如 C++ 原生模块),则需要单独检查兼容性——并非所有原生模块都能在 GCF 环境中编译。
Firebase Cloud Functions 是 Google Cloud Functions 之上的封装,带有预装的 Firebase SDK 并与 Firebase 服务集成。开发者使用 firebase-functions SDK 编写代码,该 SDK 为所有 Firebase 服务提供类型化的触发器。Google Cloud Functions 是一个更底层的平台,触发器通过 Eventarc 或 Pub/Sub 显式配置。
关键区别:在 Firebase Cloud Functions 中,触发器通过调用 functions.firestore.document('path').onWrite() 以声明方式注册;而在 Google Cloud Functions 中,则通过 Eventarc 配置并按事件属性过滤。Firebase Cloud Functions 还自动附带 Admin SDK,以项目服务账号的权限初始化,从而无需额外配置即可完全访问所有 Firebase 服务。
Firebase Cloud Functions 支持 8 类触发器,每一类对应特定的 Firebase 或 Google Cloud 服务。触发器是一个条件,当条件满足时函数被自动调用。开发者不直接管理函数的生命周期:Firebase CLI 在 Google Cloud Eventarc 中注册触发器,云平台在事件发生时自行启动函数。
最流行的触发器是 Firestore 触发器:onWrite、onCreate、onUpdate、onDelete。它们在 Firestore 集合中的文档发生更改时触发。函数会获得更改前后文档的快照,从而可以比较值并仅对特定更改做出反应。例如,当订单状态从"pending"变为"shipped"时,可以向用户发送推送通知。
Authentication 触发器(onCreate、onDelete)在创建或删除账号时触发。它们用于初始化用户数据:在 Firestore 中创建用户文档、发送欢迎邮件、写入分析。重要提示:函数无法取消用户的创建——它在账号已经创建之后执行。对于预验证,请使用 Identity Platform 平台上可用的阻塞函数(Blocking Functions)。
| 触发器类别 | 事件 | 使用示例 |
|---|---|---|
| Firestore | onWrite, onCreate, onUpdate, onDelete | 添加时更新点赞计数器 |
| Authentication | onCreate, onDelete | 注册时创建用户资料 |
| Realtime DB | onWrite, onCreate, onUpdate, onDelete | 聊天消息审核 |
| Storage | onFinalize, onArchive, onDelete | 图片上传后生成缩略图 |
| Pub/Sub | onPublish | 通过 Cloud Scheduler 定期运行(cron) |
| HTTPS | onRequest | 供外部服务使用的 REST API 端点 |
HTTPS 函数(onRequest)允许创建可通过 HTTP 访问的完整 REST API 端点。与事件触发器不同,HTTPS 函数通过形如 https://{region}-{project}.cloudfunctions.net/{functionName} 的 URL 调用。如果端点从浏览器或移动应用调用,则正确配置 CORS 很重要。Firebase SDK 不会自动包含 CORS 头——需要通过中间件手动添加。
对于移动客户端(Android、iOS),不需要 CORS,因为原生 HTTP 客户端不受跨源策略的限制。CORS 仅对 Web 请求有意义。如果您的 HTTPS 函数同时从应用和 Web 调用,请添加通用的 CORS 处理:开发环境使用 res.set('Access-Control-Allow-Origin', '*'),生产环境使用允许的域名列表。
对于定期执行(cron 任务),请使用 Cloud Scheduler 和 Pub/Sub 的组合。Cloud Scheduler 按计划向 Pub/Sub 主题发送消息,onPublish 触发器处理该消息。Firebase CLI 不支持直接的 cron 语法——计划通过 Google Cloud 控制台或 Terraform 以 unix-cron 格式设置:0 3 * * *(每天凌晨 3:00)。
任务示例:每日推送、清理过期数据、生成报告、与外部 API 同步。重要提示:Cloud Scheduler 是一项付费的 Google Cloud 服务(每个任务每月约 2 美元)。每次触发都算作一次单独的函数调用,并按 Cloud Functions 的标准价格计费。
Cloud Functions 开发始于通过 Firebase CLI 初始化项目:firebase init functions。该命令创建 functions/ 目录,包含 index.js(或 index.ts)模板、package.json 文件和 TypeScript 配置(如果选择了)。初始化后,只需编写一个函数,将其从模块导出,然后运行 firebase deploy --only functions 进行部署。
每个函数通过调用相应触发器的方法进行注册。HTTPS 函数示例:exports.helloWorld = functions.https.onRequest((req, res) => { res.send("Hello!"); })。Firebase 函数使用异步模型:对于事件触发器(非 HTTPS),函数必须返回 Promise。Firebase 在关闭容器之前会等待 Promise 完成。如果未返回 Promise,函数可能会在异步操作完成之前被中断。
本地开发通过 Firebase Emulator Suite 进行,其中包括 Cloud Functions 模拟器。命令 firebase emulators:start 启动一个带有函数的本地服务器,可在 http://localhost:5001 访问。模拟器在代码更改时支持热重载,并且与生产环境完全隔离,从而可以在不影响真实数据的风险下测试函数。
Cloud Functions 的依赖通过 package.json 管理。Firebase 只安装生产依赖(dependencies,而非 devDependencies)。函数包的大小会影响冷启动时间:建议最小化依赖数量。对于 Firebase Admin SDK,firebase-admin 依赖已经预先安装——无需手动添加。
机密数据(API 密钥、令牌)不应存储在函数代码中。使用 functions.config() 存储配置:firebase functions:config:set stripe.key="sk_..."。值已加密,可在运行时通过 functions.config().stripe.key 访问。对于大型序列化配置,请使用 Google Cloud Secret Manager。
Cloud Functions 中的日志记录通过 console.log、console.warn 和 console.error 进行。所有日志自动收集到 Google Cloud Logging 中,并可在 Firebase 控制台(Functions > Logs 部分)中查看。对于结构化日志记录,请使用支持 JSON 格式化和日志级别的 winston 或 pino 库。
错误处理对可靠性至关重要:Promise 中未处理的异常会以错误结束函数,之后 Firebase 以指数延迟自动重试(retry)调用。重试次数可配置:从 0 到无限。对于事件触发器,建议启用重试,以确保即使外部服务出现临时故障也能处理每个事件。
冷启动(cold start)是函数在闲置一段时间后首次调用时的延迟,此时包含代码的容器会被重新加载和初始化。根据 Firebase documentation(2026),冷启动根据包大小、依赖数量和区域持续 200 毫秒到 2 秒。对于用户界面,超过 1 秒的延迟是可感知的,并可能影响用户体验。
最小化冷启动的方法:最小化依赖、使用编译为 CommonJS 的 TypeScript、减小函数包大小、设置最小活动实例数。Firebase Cloud Functions v2(第 2 代)允许设置 minInstances——始终保持就绪可处理请求的预热容器的最小数量。预热容器会收取闲置时间费用。
Cloud Functions 的扩展自动进行:当请求数量增加时,Firebase 会创建新容器。默认情况下,并行实例的最大数量为 3000(Google Cloud 项目配额)。每个实例同时处理一个请求。如果函数很快(低于 100 毫秒),一个实例每秒最多可处理 10 个请求,从而使每个项目每秒的峰值吞吐量达到 30 000 个请求。
minInstances 是一个参数,它预留指定数量的容器并保持它们预热。建议用于冷启动延迟不可接受的临界 HTTPS 函数。例如,对于身份验证端点设置 minInstances: 1。maxInstances 是并行实例最大数量的限制,用于防止流量突然激增时成本不受控制地增长。
配置在代码中完成:functions.runWith({ minInstances: 1, maxInstances: 10 })。重要提示:minInstances 会增加成本,因为容器持续运行。对于测试项目,应关闭 minInstances。对于生产环境,建议所有公开的 HTTPS 函数都设置 minInstances,事件触发器设置为 0,因为那里 1 秒的延迟并不关键。
部署区域影响到达最终用户的延迟和出站流量的成本。Firebase Cloud Functions 在 30 多个 Google Cloud 区域可用。对于移动应用,请选择最靠近目标受众的区域:美洲使用 us-central1,欧洲使用 europe-west1,亚洲使用 asia-east2。部署后,如果不重新部署函数,区域无法更改。
区域的更改通过代码中的 region 参数进行:functions.region('europe-west1')。一个文件中的所有函数可以具有不同的区域。对于全球项目,建议在多个区域部署函数,并使用 Cloud Load Balancing 分配流量,不过对于大多数移动应用,只要选择正确,一个区域就足够了。
我们来看一下 TypeScript 中 Cloud Functions 的实际示例。代码使用 Firebase Functions SDK v2(第 2 代)和 ES 模块语法。示例包括处理用户创建事件、图片上传时生成缩略图以及用于 REST API 的简单 HTTPS 端点。所有函数都是异步的,并返回 Promise 以正确完成容器。
运行前,请确保 Firebase CLI 已更新到 13+ 版本:npm install -g firebase-tools。v2 函数需要 Blaze 计费方案。初始化:firebase init functions 并选择 TypeScript。
第一个示例——新用户注册时在 Firestore 中创建文档。函数由 auth.user().onCreate 事件触发,并将基本资料写入 users/{uid} 集合。这样可以保证每个注册用户都存在一个包含必要字段的文档。
import * as functions from "firebase-functions"
import * as admin from "firebase-admin"
admin.initializeApp()
export const createUserProfile = functions.auth
.user()
.onCreate(async (user) => {
const profile = {
email: user.email,
displayName: user.displayName ?? "User",
createdAt: admin.firestore.Timestamp.now(),
role: "free",
avatarUrl: null,
}
await admin.firestore()
.collection("users")
.doc(user.uid)
.set(profile)
console.log(`Profile created for ${user.uid}`)
})
createUserProfile 函数是异步的——它返回 Firebase 在完成前等待的 Promise。如果写入 Firestore 以错误结束(例如由于缺少权限),函数将自动重试(如果启用了 retry)。值为"free"的 role 字段允许直接在 Firestore 的 Security Rules 中实现免费方案的限制,将 resource.data.role 与所需的访问级别进行比较。
第二个示例——Storage 触发器,用于在图片上传后自动生成缩略图。函数创建 200x200 像素的缩小副本,并将其保存到源文件路径,前缀为 thumb_。图像处理使用 sharp 库,它支持所有常见格式,并在没有系统依赖的 Node.js 环境中运行。
import * as path from "path"
import * as os from "os"
import * as sharp from "sharp"
export const generateThumbnail = functions.storage
.object()
.onFinalize(async (object) => {
if (!object.contentType?.startsWith("image/")) return
const filePath = object.name!
const thumbPath = filePath.replace(
/(\.\w+)$/, "_thumb$1"
)
const bucket = admin.storage().bucket()
const tempDir = os.tmpdir()
const tempFile = path.join(tempDir, path.basename(filePath))
await bucket.file(filePath).download({ destination: tempFile })
await sharp(tempFile)
.resize(200, 200, { fit: "cover" })
.toFile(tempFile.replace(/(\.\w+)$/, "_thumb$1"))
await bucket.upload(tempFile.replace(
/(\.\w+)$/, "_thumb$1"
), { destination: thumbPath })
})
generateThumbnail 函数检查对象的 Content-Type 并忽略非图像,从而节省资源。使用 sharp 需要将依赖添加到 package.json。缩略图使用 fit: "cover" 参数创建,该参数将图像居中裁剪为 200x200 像素的正方形。创建后,缩略图以修改后的名称上传回同一个存储桶。
第三个示例——HTTPS 函数,实现用于检查服务器状态的 REST API 端点。函数接受 GET 请求并返回 JSON,其中包含连接到项目的 Firebase 服务状态信息。该端点对于监控以及需要在发送数据前检查后端可用性的外部系统非常有用。
import * as express from "express"
const app = express.Router()
app.get("/status", async (req, res) => {
try {
const db = admin.firestore()
await db.collection("_health").doc("check").get()
res.json({ status: "ok", timestamp: Date.now() })
} catch (error) {
res.status(503).json({ status: "error", message: error })
}
})
export const api = functions.https.onRequest(app)
api 函数使用 express Router 进行路由,这在一个函数中创建多个端点时很方便。健康检查写入 Firestore 的 _health 集合,从而可以同时检查 Firestore 的可用性。对于生产环境,建议通过 API 密钥或 Firebase Auth 令牌添加请求身份验证,以防止公共端点被滥用。
Cloud Functions 最常用于无法或不宜在客户端执行的任务:发送推送通知、生成上传图片的预览、与外部支付系统集成、内容审核、Firebase 与第三方服务之间的数据同步。无服务器模式使这些任务经济高效:只按代码的实际运行时间收费。
与支付系统集成是带有应用内购买的应用的典型场景。Cloud Functions 从支付提供商(Stripe、PayPal)接收 webhook,验证请求签名,更新 Firestore 中的订阅状态,并向用户发送确认。所有代码都在服务器上运行,没有客户端数据被篡改的风险。根据 Stripe documentation(2026),webhook 处理时间不到 500 毫秒。
智能内容审核使用 Storage 触发器通过 Google Cloud Vision API 自动检查上传的图片。函数将图片发送到 Vision API 以检测不安全内容(暴力、成人内容),如果超过阈值,则删除文件并通知管理员。这个场景对于具有用户画廊的 UGC 应用至关重要。
数据聚合——Cloud Functions 作为 Firebase Realtime Database 计数器的替代品。不要在客户端读取和写入计数器(这会导致竞态条件),而是使用 Firestore 的 onWrite 触发器原子地更新聚合字段。例如,函数在 /posts/{postId}/likes/{userId} 子集合中每次添加或删除文档时计算帖子的点赞数量,并更新父文档中的 likesCount 字段。
常见问题
最大执行时间取决于类型:HTTPS 函数为 9 分钟,事件触发器为 60 秒(v2:最长 60 分钟)。对于长时间操作,请使用 Cloud Tasks 或 Pub/Sub 进行异步处理。超时通过 runWith({ timeoutSeconds: 120 }) 在代码中设置。
使用 Firebase Emulator Suite:firebase emulators:start --only functions。模拟器在 5001 端口本地运行函数,并支持热重载。对于 Firestore 和 Auth 触发器,模拟器会替换真实服务,从而可以在不影响生产数据的风险下测试各种场景。
第 2 代使用 Google Cloud Run 和 Eventarc,提供更长的超时时间(最长 60 分钟)、单个实例并发处理请求以及与 Google Cloud 服务更好的集成。第 1 代使用 Google Cloud Functions,事件函数限制为 60 秒。Firebase 建议新项目从第 2 代开始。
Firebase Cloud Functions 官方只支持 Node.js(JavaScript 和 TypeScript)。对于 Python,请直接使用 Google Cloud Functions 和适用于 Python 的 Firebase Admin SDK。Firebase Admin SDK Python 支持所有操作,但某些仅通过 Node.js 可用的 Firebase 特有触发器除外。
对于经过身份验证的访问,请在 Authorization 标头中验证 Firebase ID 令牌:admin.auth().verifyIdToken(token)。对于服务器到服务器集成,请使用带服务账号或 API 密钥的 Firebase Admin SDK。对于有速率限制的公共端点,请通过 Cloud Armor 或中间件使用速率限制。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。