如何在Jenkins中运行Firebase模拟器测试Firestore安全规则?
Jenkins环境下通过Firebase Emulator运行Firestore规则测试的可行方案
你碰到的RST_STREAM with code 2连接错误,核心原因是直接执行测试脚本时,Firestore客户端默认会尝试连接公网Firestore服务,Jenkins节点的出口网络限制、gRPC协议拦截、代理配置问题都会触发这个报错。完全不需要打通公网到Firestore的访问,直接在流水线内拉起本地Firebase模拟器跑测试是成熟可行的方案,具体配置如下:
第一步:调整本地测试逻辑,强制走模拟器
先修改测试初始化代码,确保测试完全不依赖公网服务,本地断网也能跑通:
- 在mocha的全局初始化入口(比如
test/setup.js)最顶部,添加模拟器地址的环境变量配置:
// 必须在引入firebase SDK之前配置 process.env.FIRESTORE_EMULATOR_HOST = 'localhost:8080'; // 如果测试规则依赖鉴权逻辑,同时配置鉴权模拟器地址 process.env.FIREBASE_AUTH_EMULATOR_HOST = 'localhost:9099'; const firebase = require('@firebase/testing'); // 初始化测试客户端时不需要填线上项目凭证,随便指定一个测试用项目ID即可 const getTestApp = () => firebase.initializeTestApp({ projectId: 'ci-test-project', // 如果用7.x版本SDK存在gRPC兼容问题,加下面这个配置强制走长轮询绕过流协议错误 firestore: { experimentalForceLongPolling: true } });
- 本地验证:断开公网、退出Firebase账号后执行
yarn test,确认所有用例正常通过,再提交代码。
第二步:配置Jenkins节点基础依赖
Jenkins运行节点需要预装和本地开发版本对齐的依赖,避免版本兼容问题:
- Node.js(和本地大版本保持一致,推荐16/18 LTS版本)
- Yarn包管理器
- Firebase CLI:执行
npm install -g firebase-tools@<你本地使用的版本号>全局安装,不要直接装latest版本,大版本迭代经常改动模拟器启动逻辑,和本地版本对齐能规避绝大多数奇怪问题 - Java 11+运行环境:Firebase模拟器依赖JRE运行,缺Java会直接启动失败
- netcat工具:用于流水线内检测模拟器是否启动就绪
第三步:调整Jenkins流水线逻辑
流水线不要直接执行yarn test,要按照「启动模拟器→等待服务就绪→执行测试→无论成败关停模拟器」的顺序编排,示例流水线片段:
pipeline { agent any environment { FIREBASE_CI_TOKEN = credentials('firebase-deploy-token') // 你之前存的Firebase发布凭证 } stages { stage('安装依赖') { steps { sh 'yarn install --frozen-lockfile' } } stage('Firestore规则单元测试') { steps { script { // 后台启动需要的模拟器,只开firestore、auth即可,多余的服务不要启动减少资源占用 sh 'npx firebase emulators:start --only firestore,auth --project ci-test-project > emulator.log 2>&1 &' // 轮询检测模拟器端口,最多等待30秒直到服务就绪 waitUntil(initialRecurrencePeriod: 3000, timeout: 30) { return sh(script: 'nc -z localhost 8080', returnStatus: true) == 0 } try { sh 'yarn test' } finally { // 测试不管成功失败都杀掉模拟器进程,避免下次构建端口占用 sh 'pkill -f firebase-tools || true' // 归档模拟器日志,方便出问题时排查 archiveArtifacts artifacts: 'emulator.log', allowEmptyArchive: true } } } } stage('发布规则到develop环境') { when { branch 'develop' } steps { // 测试通过后再执行你原来的发布逻辑 sh 'npx firebase deploy --only firestore:rules --project 你的线上项目ID --token $FIREBASE_CI_TOKEN' } } } }
常见踩坑说明
- 如果Jenkins任务跑在Docker容器内,不要用精简版alpine基础镜像,提前把JDK、netcat依赖打包进镜像,否则模拟器会启动失败
- 如果用7.x版本的Firebase JS SDK一直报流错误,直接升级到8.x以上版本,7.x版本对模拟器的gRPC支持存在已知bug
- 跑本地模拟器不需要Firebase登录凭证,不要在流水线里加
firebase login相关步骤,只有发布到线上时才需要用到CI token - 如果Jenkins节点配置了全局HTTP代理,记得给
localhost、127.0.0.1加no_proxy白名单,否则客户端会把模拟器请求走代理转发导致连接失败
内容的提问来源于stack exchange,提问作者Ale TheFe
相关产品推荐
相关产品推荐

