Firebase模拟器触发RST_STREAM协议错误的排查求助
问题:Firebase Admin连接Firestore模拟器触发RST_STREAM协议错误
在Node.js/SvelteKit服务端端点环境下,使用Firebase Admin连接Firestore模拟器时,每次请求都会触发以下错误:
code: 13, details: 'Received RST_STREAM with code 2 triggered by internal client error: Protocol error', metadata: Metadata { internalRepr: Map(0) {}, options: {} }, note: 'Exception occurred in retry method that was not classified as transient'
依赖版本信息
pnpm view firebase-admin dependencies
{ '@fastify/busboy': '^1.1.0', '@firebase/database-compat': '^0.3.0', '@firebase/database-types': '^0.10.0', '@types/node': '>=12.12.47', jsonwebtoken: '^9.0.0', 'jwks-rsa': '^3.0.1', 'node-forge': '^1.3.1', uuid: '^9.0.0', '@google-cloud/firestore': '^6.4.0', '@google-cloud/storage': '^6.5.2' }
相关代码
firebaseInit.js
import admin from 'firebase-admin' const useEmulator = true; if (useEmulator){ process.env['FIRESTORE_EMULATOR_HOST'] = 'localhost:4000'; } const firebaseConfig = { apiKey: "XXXXX", authDomain: "linkedincv-bdbec.firebaseapp.com", projectId: "linkedincv-bdbec", storageBucket: "linkedincv-bdbec.appspot.com", messagingSenderId: "XXXXX", appId: "XXXXX", measurementId: "XXXXX", }; const app = admin.initializeApp(firebaseConfig); const db = admin.firestore(); export {app, db}
+server.js
import { json } from '@sveltejs/kit'; import {db} from '../../../lib/middleware/firebaseInit' export async function POST({request}) { try { const payload = await request.json(); const uniqueUrl = payload.uniqueUrl; const docRef = await db.collection("json_cv").doc("zied").set( payload) return json({ body: JSON.stringify({ documentId: docRef.id }), headers: { 'Content-Type': 'application/json' }, status: 200 }); } catch (error) { console.error(error); return json({ body: JSON.stringify({ error }), headers: { 'Content-Type': 'application/json' }, status: 500 }); } }
hooks.server.js(CORS配置)
import { Handle } from '@sveltejs/kit'; export const handle = async ({ resolve, event }) => { const response = await resolve(event); if (event.url.pathname.startsWith('/cv/submit')) { if(event.request.method === 'OPTIONS') { return new Response(null, { headers: { 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, DELETE', 'Access-Control-Allow-Origin': '*', } }); } response.headers.append('Access-Control-Allow-Origin', `*`); } return response; };
注:已知该问题在GitHub有相关议题讨论,但并非必现,需排查解决。
排查与解决建议
1. 提前设置模拟器环境变量
Firebase Admin初始化时需要读取环境变量,将FIRESTORE_EMULATOR_HOST的设置移到文件最顶部,确保在初始化前生效:
import admin from 'firebase-admin' const useEmulator = true; // 提前设置环境变量 if (useEmulator){ process.env['FIRESTORE_EMULATOR_HOST'] = 'localhost:4000'; process.env['FIRESTORE_EMULATOR_SSL_ENABLED'] = 'false'; } // 后续初始化代码不变
2. 调整@google-cloud/firestore版本
当前@google-cloud/firestore@6.4.0可能存在模拟器兼容性问题,尝试:
- 降级到
6.0.0或升级到最新稳定版(如7.x系列) - 执行命令更新:
pnpm add @google-cloud/firestore@latest
3. 显式配置模拟器地址
绕过环境变量,直接用settings方法指定模拟器参数:
const db = admin.firestore(); if (useEmulator) { db.settings({ host: 'localhost:4000', ssl: false }); }
4. 重启服务与模拟器
SvelteKit开发服务器或Firebase模拟器可能存在连接缓存问题,尝试:
- 关闭并重新启动Firebase模拟器
- 重启SvelteKit开发服务
5. 禁用HTTP/2协议
部分场景下HTTP/2与模拟器不兼容,强制使用HTTP/1.1:
const db = admin.firestore(); if (useEmulator) { db.settings({ host: 'localhost:4000', ssl: false, http2: false }); }
内容的提问来源于stack exchange,提问作者Zied Hamdi
相关产品推荐
相关产品推荐

