将 Crashlytics 和(可选)Firebase 会话数据导出到 BigQuery 后,您就可以开始使用这些数据了:
使用 SQL 查询分析数据
您可以对 Crashlytics 数据运行查询,以生成自定义报告和摘要。由于 Firebase 控制台的 Crashlytics 信息中心内不提供这类自定义报告,因此这些报告可以补充您对崩溃数据的分析和理解。请参阅本页面后面的示例查询集合。联接来自不同数据集的数据
例如,如果您在设置 Crashlytics 数据导出时选择导出 Firebase 会话数据,则可以更好地了解“未遇到崩溃问题的用户数”和“未发生崩溃问题的会话数”(请参阅查询示例)。 此外,您还可以从各种 Firebase 产品(例如 Performance Monitoring)或从 Google Analytics 导出数据,然后在 BigQuery 中将这些数据与 Crashlytics 数据联接起来并进行分析。创建视图
您可以使用 BigQuery 界面创建“视图”,它是由 SQL 查询定义的虚拟表。如需详细了解不同类型的视图及其创建方法,请参阅 BigQuery 文档。
如需详细了解数据集架构,请参阅BigQuery 中导出数据的数据集架构。
了解 BigQuery SQL
了解可以运行的查询类型,包括交互式查询作业、批量查询作业和持续查询作业。
了解 BigQuery 中支持的语句和 SQL 方言。
Crashlytics 数据的查询示例
本部分提供了一些示例情况和示例查询,展示了如何将 BigQuery SQL 与导出的 Crashlytics 数据和 Firebase 会话数据搭配使用。
- 使用 Firebase 会话数据计算“未遇到崩溃问题”指标
- 按天统计的崩溃次数
- 查找最普遍的崩溃
- 10 大易崩溃设备
- 按自定义键过滤
- 提取用户 ID
- 查找面临特定崩溃问题的所有用户
- 受崩溃问题影响的用户数量,按国家/地区细分
- 今天到现在为止的 5 大问题
- 自 DATE 起至今(包括今天)的 5 大问题
示例 1:使用 Firebase 会话数据计算“未遇到崩溃问题”指标
在最新版本中,您对应用进行了重大改版,以解决关键用户历程中的崩溃问题。您收到了用户的好评,但希望获得定量证据来证明您的应用比以前更稳定。
“未遇到崩溃问题”指标可帮助您获取此信息。这些指标是重要的衡量标准,可帮助您了解应用的总体健康状况。借助 Firebase 会话数据和 Crashlytics 事件,您可以通过基本查询计算这些指标。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
特定版本的未遇到崩溃问题的用户数:
SELECT TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) AS event_date, (1 - (COUNT (DISTINCT installation_uuid) / COUNT (DISTINCT instance_id))) AS CFU FROM `PROJECT_ID.firebase_sessions.PACKAGE_NAME_ANDROID` AS sessions LEFT JOIN `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` AS crashlytics ON TIMESTAMP_TRUNC(sessions.event_timestamp,DAY) = TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) WHERE crashlytics.error_type="FATAL" AND crashlytics.application.display_version="APP_VERSION" AND sessions.application.display_version = "APP_VERSION" GROUP BY event_date ORDER BY event_date
过去一周(过去 168 小时)未发生崩溃问题的会话:
SELECT TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) AS event_date, (1 - (COUNT (DISTINCT crashlytics.firebase_session_id) / COUNT (DISTINCT sessions.session_id))) AS CFS FROM `PROJECT_ID.firebase_sessions.PACKAGE_NAME_ANDROID` AS sessions LEFT JOIN `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` AS crashlytics ON TIMESTAMP_TRUNC(sessions.event_timestamp,DAY) = TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) WHERE crashlytics.error_type="FATAL" AND _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 168 HOUR) AND _PARTITIONTIME < CURRENT_TIMESTAMP() GROUP BY event_date ORDER BY event_date
示例 2:每天的崩溃次数
在努力解决尽可能多的 bug 之后,您认为自己的团队终于做好了准备,可以推出全新的照片共享应用。在推出之前,您想检查一下过去一个月内每天的崩溃次数,以确保这次大规模的纠错让应用的运行更加稳定了。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT COUNT(DISTINCT event_id) AS number_of_crashes, FORMAT_TIMESTAMP("%F", event_timestamp) AS date_of_crashes FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` GROUP BY date_of_crashes ORDER BY date_of_crashes DESC LIMIT 30;
示例 3:查找最普遍的崩溃
为了适当排定生产计划的优先级,您需要找出应用中 10 个最普遍的崩溃。您可以生成一个查询,以提供相关数据。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT DISTINCT issue_id, COUNT(DISTINCT event_id) AS number_of_crashes, COUNT(DISTINCT installation_uuid) AS number_of_impacted_user, blame_frame.file, blame_frame.line FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` WHERE event_timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(),INTERVAL 168 HOUR) AND event_timestamp < CURRENT_TIMESTAMP() GROUP BY issue_id, blame_frame.file, blame_frame.line ORDER BY number_of_crashes DESC LIMIT 10;
示例 4:10 大易崩溃设备
秋季是新手机的发布季!贵公司知道,这也意味着又到了解决新设备特有的问题的季节,尤其是 Android 设备。为了针对很可能出现的兼容性问题而未雨绸缪,您编写了一个查询,可以识别过去一周(168 小时)里出现最多崩溃的 10 款设备。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT device.model, COUNT(DISTINCT event_id) AS number_of_crashes FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` WHERE event_timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 168 HOUR) AND event_timestamp < CURRENT_TIMESTAMP() GROUP BY device.model ORDER BY number_of_crashes DESC LIMIT 10;
示例 5:按自定义键过滤
您是游戏开发者,想知道游戏崩溃次数最频繁的是哪个关卡。
为了帮助跟踪该统计信息,您可以设置一个名为 current_level 的自定义 Crashlytics 键(iOS+ | Android | Flutter | Unity),并在用户每次达到新级别时更新该键。
Swift
Crashlytics.sharedInstance().setIntValue(3, forKey: "current_level");
Objective-C
CrashlyticsKit setIntValue:3 forKey:@"current_level";
Java
Crashlytics.setInt("current_level", 3);
在导出到 BigQuery 的数据中使用该键,您可以编写一个查询来报告与各个崩溃事件相关联的 current_level 值的分布情况。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT
COUNT(DISTINCT event_id) AS num_of_crashes,
value
FROM
`PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
UNNEST(custom_keys)
WHERE
key = "current_level"
GROUP BY
key,
value
ORDER BY
num_of_crashes DESC示例 6:提取用户 ID
您有一个处于抢先体验阶段的 Android 应用。该应用的大多数用户都很喜欢它,但有三位用户遇到了异常数量的崩溃。为了确定该问题的根源,您编写了一个查询,按照用户 ID 拉取这些用户的所有崩溃事件。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT *
FROM
`PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
WHERE
user.id IN ("USER_ID_1", "USER_ID_2", "USER_ID_3")
ORDER BY
user.id
示例 7:查找面临特定崩溃问题的所有用户
您的团队向一组 Beta 版测试人员发布的版本中包含一个严重 bug。您的团队可以使用上面“查找最普遍的崩溃”示例中的查询来识别这一特定崩溃问题的 ID。现在,您的团队想要运行查询来提取受此崩溃影响的应用用户列表。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT user.id as user_id
FROM
`PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
WHERE
issue_id = "ISSUE_ID"
AND application.display_version = "APP_VERSION"
AND user.id != ""
ORDER BY
user.id;示例 8:受崩溃问题影响的用户数量,按国家/地区细分
您的团队在发布新版本期间发现了一个严重 bug。您可以使用上面“查找最普遍的崩溃”示例中的查询来识别特定崩溃问题的 ID。您的团队现在想要确认该崩溃是否已蔓延至全球不同国家/地区的用户。
为了编写此查询,您的团队将需要执行以下操作:
启用将 Google Analytics 数据导出到 BigQuery 的功能。请参阅将项目数据导出到 BigQuery。
更新应用以将用户 ID 传递到 Google Analytics SDK 和 Crashlytics SDK。
Swift
Crashlytics.sharedInstance().setUserIdentifier("123456789"); Analytics.setUserID("123456789");Objective-C
CrashlyticsKit setUserIdentifier:@"123456789"; FIRAnalytics setUserID:@"12345678 9";Java
Crashlytics.setUserIdentifier("123456789"); mFirebaseAnalytics.setUserId("123456789");编写一个查询,通过用户 ID 字段将 Google Analytics 数据集中的事件与 Crashlytics 数据集中的崩溃联接:
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和
IOS(而不是软件包名称和ANDROID)。SELECT DISTINCT c.issue_id, a.geo.country, COUNT(DISTINCT c.user.id) as num_users_impacted FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` c INNER JOIN `PROJECT_ID.analytics_TABLE_NAME.events_*` a on c.user.id = a.user_id WHERE c.issue_id = "ISSUE_ID" AND a._TABLE_SUFFIX BETWEEN '20190101' AND '20200101' GROUP BY c.issue_id, a.geo.country, c.user.id
示例 9:今天到现在为止的 5 大问题
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT issue_id, COUNT(DISTINCT event_id) AS events FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID_REALTIME` WHERE DATE(event_timestamp) = CURRENT_DATE() GROUP BY issue_id ORDER BY events DESC LIMIT 5;
示例 10:自 DATE 起至今(包括今天)的 5 大问题
您还可以将批量表和实时表与拼接查询结合使用,以便将实时信息添加到可靠的批量数据中。由于 event_id 是主键,因此您可以使用 DISTINCT event_id 对两个表中的任何常见事件进行重复数据删除。
以下是 Android 应用的示例查询。对于 iOS 应用,请使用其软件包 ID 和 IOS(而不是软件包名称和 ANDROID)。
SELECT issue_id, COUNT(DISTINCT event_id) AS events FROM ( SELECT issue_id, event_id, event_timestamp FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID_REALTIME` UNION ALL SELECT issue_id, event_id, event_timestamp FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`) WHERE event_timestamp >= PARSE_TIMESTAMP("%Y_%m_%d", "YYYY_MM_DD") GROUP BY issue_id ORDER BY events DESC LIMIT 5;
后续步骤
使用导出的数据和各种 Google Cloud 服务(例如 Looker Studio)构建自定义信息中心。
了解导出数据的数据集架构。