Firebase Cloud Functions中Server-Sent Events(SSE)流式返回问题
Firebase Cloud Functions 实现SSE流式响应的问题与解决方案
核心结论
Firebase Cloud Functions的标准第一代环境不支持HTTP流式响应,平台会缓存所有输出数据,直到函数执行完毕才一次性返回给客户端,所以你在代码里调用response.flush()也无法实时推送数据。
原因分析
第一代Cloud Functions基于无状态的请求-响应模型,函数必须在超时时间(最长90秒)内完成执行,平台会缓冲所有响应内容,只有当函数调用结束(比如执行response.end())时才会把全部数据发送给客户端,这就导致SSE的实时推送逻辑无法生效。
解决方案:使用第二代Cloud Functions + 流式响应
第二代Cloud Functions(2nd gen)支持HTTP流式响应,能够实现实时推送数据的需求。下面是修改后的代码:
服务端代码(functions/index.js)
const { onRequest } = require("firebase-functions/v2/https"); const express = require("express"); const app = express(); app.get("/sse", (request, response) => { // 设置SSE响应头 response.setHeader("Content-Type", "text/event-stream"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Connection", "keep-alive"); response.setHeader("Access-Control-Allow-Origin", "*"); // 根据实际需求调整跨域配置 // 发送初始连接消息 response.write("data: Connected\n\n"); // 每秒推送数据 const intervalId = setInterval(() => { const data = { message: "Hello world!" }; response.write(`data: ${JSON.stringify(data)}\n\n`); // 第二代函数中无需手动flush,平台会自动推送已写入的数据 }, 1000); // 客户端断开连接时清理资源 request.on("close", () => { clearInterval(intervalId); response.end(); }); }); // 导出第二代HTTP函数 exports.sseFunction = onRequest(app);
注意:
- 第二代函数需要安装
firebase-functions@v2及以上版本,且需在firebase.json中配置函数运行时为Node.js 18+ - 第二代函数的超时时间最长可设置为3600秒(1小时),适配长连接场景
客户端代码
你的客户端代码无需修改,保持原有EventSource逻辑即可:
export const sseFunctionStream = async () => { const eventSource = new EventSource( "https://us-central1-<project-id>.cloudfunctions.net/sseFunction/sse" ); eventSource.addEventListener("message", (event) => { const data = JSON.parse(event.data); console.log(data); }); return () => { eventSource.close(); }; };
替代方案:使用Firebase实时数据库/ Firestore实现实时更新
如果暂时无法升级到第二代函数,可以通过Firebase Realtime Database或者Firestore的实时监听功能,模拟SSE的效果:
- 服务端函数定期将数据写入数据库
- 客户端通过Firebase SDK监听数据库变化,实时获取更新
这种方式虽不是服务器主动推送的SSE,但同样能实现客户端实时接收数据的需求。
内容的提问来源于stack exchange,提问作者Zack
相关产品推荐
相关产品推荐

