Firebase 还会发送稳定性摘要(
onStabilityDigestPublished),按天汇总多个热门问题;这是一份周期性报告而非单个可处理的问题,本集成不会把它转成告警。
在 Flashduty On-call
您可通过以下两种方式获取集成推送地址,任选其一即可。
使用专属集成
- 进入 Flashduty 控制台,选择 协作空间,打开一个协作空间
- 选择 配置 → 集成数据 → 专属集成,点击 新增一个集成
- 选择 Firebase Crashlytics,点击 保存
- 打开生成的集成卡片,复制 推送地址
使用共享集成
- 进入 Flashduty 控制台,选择 集成中心 → 告警事件
- 选择 Firebase Crashlytics,填写集成名称
- 配置默认路由并选择协作空间;创建后可在 路由 中增加更多规则
- 点击 保存,复制生成的 推送地址
在 Firebase 中配置
Crashlytics 告警函数运行在 Cloud Functions(2nd gen)之上,Firebase 项目需要在 Blaze(按量付费) 方案下才能部署,即使实际用量落在免费额度内也需要绑定结算账号。
1
准备 Cloud Functions 项目
如果项目还没有初始化 Cloud Functions,在项目根目录执行:选择 JavaScript 或 TypeScript,安装依赖时保留默认的
firebase-functions 和 firebase-admin。2
写入转发函数
把 字段名和取值路径都来自
functions/index.js(或对应的入口文件)替换或追加为以下内容,将 FLASHDUTY_URL 换成上一步复制的推送地址(包含 ?integration_key=...):firebase-functions 的官方类型定义,不要改名:event.alertType、event.appId、event.data.createTime 和 event.data.payload.issue 是每种事件共有的字段,resolveTime 只在回归事件中存在,crashCount/crashPercentage/firstVersion 只在速率告警中存在。函数使用 Node.js 18 及以上运行时内置的 fetch,不需要额外安装 HTTP 客户端库。如果只想接入其中几类事件,删掉不需要的 require 项和对应的 exports 行即可;不要修改保留下来的字段名。3
按需限定应用
如果 Firebase 项目下有多个应用(iOS、Android、Web 各一个 App ID),且只想接入其中一个,把
onXxxPublished(handler) 换成 onXxxPublished(appId, handler),appId 取自 项目设置 → 常规 → 应用的应用 ID。不传 appId 时,项目下所有应用的事件都会转发。4
部署
5
验证
Crashlytics 告警没有测试按钮,用以下两种方式分别验证:
-
验证 Flashduty 一侧:用上面模板中的字段结构,向推送地址发一次 curl 请求确认能建立告警:
验证后请在 Flashduty 中手动关闭这条测试告警。
-
验证完整链路:在一个 Debug 构建中触发一次真实崩溃(例如调用
Crashlytics.crash()/FirebaseCrashlytics.getInstance().log(...)后强制抛异常),等待该问题出现在 Crashlytics 控制台(可能有几分钟延迟),确认 Flashduty 收到对应告警。
6
开启超时自动关闭
Crashlytics 不会为这些事件发送“已解决”通知,Flashduty 中的告警不会自动恢复。请在接收该集成告警的协作空间中开启 超时自动关闭,超时计时起点选择 故障触发,超时时长建议设置为 72 小时(崩溃问题的排查和发版周期通常比一般基础设施故障更长),配置方法参阅 配置协作空间。问题修复并发布新版本后,可以在 Flashduty 中手动关闭告警。
Alert Key
Flashduty 使用事件类型
alert_type、应用 ID app_id 和 Crashlytics 的问题 ID issue_id(对应官方 Issue.id)共同计算 Alert Key。一个 Cloud Function 部署(一个推送地址)可以转发项目下所有应用的事件(见上文“按需限定应用”),而 Firebase 并未说明 issue_id 在不同应用之间也互不重复,因此 app_id 也参与计算,避免两个应用凑巧拿到相同的问题 ID 时被合并成一条告警。因此:
- 同一应用、同一问题的同一类事件(例如两次
newFatalIssue投递,Eventarc 可能重试)落在同一条告警上 - 同一应用、同一问题先后触发新增致命问题和速率告警,是两条独立的告警
- 一个曾被标记为已解决的问题再次出现(
regression)会开一条新的告警,不会复用之前newFatalIssue的那条 - 问题标题、副标题、应用版本号和时间戳的变化都不会改变 Alert Key
issue_id 时,Flashduty 会拒绝该请求。
告警等级
Crashlytics 的告警事件不携带等级,Flashduty 按事件类型确定等级:
如需统一改为其他等级,在推送地址后追加
&severity=Critical(或 Warning、Info)。
告警内容
告警标题为
Firebase Crashlytics <事件类型>: <issue_title>,如 Firebase Crashlytics new fatal issue: java.lang.NullPointerException。描述包含问题副标题(崩溃发生的类和方法)、应用版本号;回归事件额外包含上次被标记解决的时间,速率告警额外包含崩溃会话数、崩溃率和首次出现的版本号。
排查问题
- 函数部署失败或报权限错误:确认 Firebase 项目已开通 Blaze 方案,且执行部署的账号对该项目有 Cloud Functions 部署权限
- 崩溃已发生,但迟迟没有告警:Crashlytics 处理崩溃日志和触发告警函数通常有几分钟延迟;用
firebase functions:log查看对应函数有没有被触发、fetch有没有抛错 - Flashduty 返回参数错误:多数情况是模板中的字段名被改动,或推送地址中的
integration_key不属于本集成;对照上面的模板逐字核对 - 告警一直不恢复:Crashlytics 的这些事件都不带恢复信号,请开启协作空间的超时自动关闭,或在问题修复后手动关闭
firebase-functions 源码 alerts/crashlytics。