CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Flutter 开发入门/课时/分析与监控
RawBlame
课时目录12 节

Flutter 开发入门

  1. 01Flutter 环境
  2. 02Dart 语言
  3. 03Widget 体系
  4. 04架构原则
  5. 05状态管理
  6. 06动画
  7. 07网络与本地存储
  8. 08Firebase 集成
  9. 09测试
  10. 10CI/CD 与发布
  11. 11分析与监控
  12. 12综合练习

分析与监控

Firebase/Mixpanel/GA。

30 分钟

分析与监控

这一课你将能做到

  1. 用 Firebase Analytics 埋点:页面浏览、自定义事件、用户属性
  2. 用 Firebase Performance Monitoring 监控 App 启动时间、网络请求、自定义 trace
  3. 用 Crashlytics 抓崩溃 + 自定义日志,搭建「数据 → 看板 → 决策」的闭环

为什么要学

上架只是开始。没有数据就是瞎开船:用户在哪一步流失?哪个页面最卡?哪个版本崩溃最多?分析和监控让这些问题有答案。

人话:Analytics 告诉你「用户在做什么」,Performance 告诉你「App 跑得多快」,Crashlytics 告诉你「App 在哪里挂了」。三件套凑齐就是 App 的「仪表盘 + 黑匣子」。

先建立图像

用户行为 ──┐
           ├──► Firebase Analytics     → 留存/漏斗/转化
App 性能 ──┼──► Firebase Performance   → 启动耗时/网络耗时
           │
崩溃异常 ──┴──► Firebase Crashlytics   → 崩溃率/堆栈/影响用户

跟着做

步骤 1:接入依赖

dependencies:
  firebase_core: ^2.24.0
  firebase_analytics: ^10.8.0
  firebase_performance: ^0.9.3
  firebase_crashlytics: ^3.4.0

main.dart 初始化(前面 Firebase 课已经讲过):

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

  FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
  PlatformDispatcher.instance.onError = (e, s) {
    FirebaseCrashlytics.instance.recordError(e, s, fatal: true);
    return true;
  };

  runApp(const MyApp());
}

步骤 2:页面浏览埋点(自动 + 手动)

Firebase Analytics 提供 FirebaseAnalyticsObserver,挂到 MaterialApp 就能自动记录路由切换:

import 'package:firebase_analytics/firebase_analytics.dart';

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  static FirebaseAnalytics analytics = FirebaseAnalytics.instance;
  static FirebaseAnalyticsObserver observer =
      FirebaseAnalyticsObserver(analytics: analytics);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorObservers: [observer],
      home: const HomePage(),
    );
  }
}

自动收集的是路由名,业务事件还是要手动埋。

步骤 3:自定义事件与用户属性

class Analytics {
  static final _a = FirebaseAnalytics.instance;

  // 自定义事件
  static Future<void> logLogin(String method) =>
      _a.logLogin(loginMethod: method);                 // 预定义事件

  static Future<void> logAddToCart(String itemId, double price) =>
      _a.logAddToCart(
        items: [AnalyticsEventItem(itemId: itemId, price: price)],
        value: price,
        currency: 'CNY',
      );

  static Future<void> logCustom(String name, Map<String, Object> params) =>
      _a.logEvent(name: name, parameters: params);

  // 用户属性(用于分群)
  static Future<void> setUserProps({required String userId, String? plan}) async {
    await _a.setUserId(id: userId);
    if (plan != null) await _a.setUserProperty(name: 'plan', value: plan);
  }
}

业务里使用:

ElevatedButton(
  onPressed: () {
    Analytics.logCustom('click_pay', {'amount': 99.0, 'from': 'home'});
    // ...
  },
  child: const Text('支付'),
)

命名规范:

  • 事件名:动词_名词,全小写下划线,如 click_pay、view_product_detail
  • 参数键:名词,如 item_id、price、from
  • 不超过 500 个事件名,每个事件 25 个参数,每个参数值 100 字符

步骤 4:性能监控

Firebase Performance 自动收集:App 启动时间、网络请求耗时(HTTP/S 自动拦截)、渲染慢帧/冻结帧(屏幕级)。

自定义 trace:跟踪任意一段代码耗时。

import 'package:firebase_performance/firebase_performance.dart';

Future<void> loadDashboard() async {
  final trace = FirebasePerformance.instance.newTrace('load_dashboard');
  await trace.start();

  await fetchUserProfile();
  trace.putAttribute('has_cache', 'true');
  trace.setMetric('item_count', 30);

  await fetchFeed();

  await trace.stop();
}

在 Firebase Console → Performance 能看到 load_dashboard 的 P50/P90/P99 耗时分布,按版本、国家、设备切片。

网络请求:Performance 自动监控 dart:io 的 HttpClient。用 dio 时需要额外配置(dio 5 已支持):

final dio = Dio();
dio.httpClientAdapter = IOHttpClientAdapter();  // 默认走 dart:io,自动被监控

步骤 5:Crashlytics 增强

import 'package:firebase_crashlytics/firebase_crashlytics.dart';

Future<void> reportLogin(String userId) async {
  // 设置用户标识,崩溃时知道是谁
  await FirebaseCrashlytics.instance.setUserIdentifier(userId);

  // 自定义键值,崩溃时一并上传
  await FirebaseCrashlytics.instance.setCustomKey('last_page', 'home');
  await FirebaseCrashlytics.instance.setCustomKey('cart_size', 3);

  // 记录面包屑日志
  FirebaseCrashlytics.instance.log('User clicked login');
}

// 主动上报非致命异常
Future<void> safeApiCall() async {
  try {
    await riskyOperation();
  } catch (e, s) {
    await FirebaseCrashlytics.instance.recordError(e, s, fatal: false);
  }
}

关键原则:

  • fatal: true:App 崩溃,下次启动时上传
  • fatal: false:非致命,立即上传,不打断用户

步骤 6:在 Firebase Console 看数据

  • Analytics → Events:每个事件的总数、用户数、触发频次
  • Analytics → Funnels:自定义漏斗,比如「首页 → 详情 → 加购 → 支付」看每一步转化
  • Performance → Custom traces:自定义 trace 的耗时分布
  • Crashlytics → Issues:按崩溃次数/影响用户排序,看堆栈定位代码行

讲清楚要点

  1. 三类数据各有分工:Analytics 看用户行为,Performance 看性能,Crashlytics 看稳定性。
  2. 埋点设计先于编码:列出核心漏斗(注册 → 激活 → 付费),只埋对决策有用的事件。
  3. 用户属性做分群:plan=free/pro、channel=organic/ads,分析时分维度切片。
  4. 自定义 trace 用在关键路径:启动、首页加载、支付,别瞎埋。
  5. 崩溃治理看 Top Issues:按影响用户数排序,每周清零 Top 5。

你可能会懵的地方

  • Firebase Analytics 免费吗? 完全免费,无配额限制。Google 通过 Analytics 数据改进广告业务。

  • 数据什么时候能看到? Analytics 实时事件 24 小时内出报表;Performance 几小时;Crashlytics 分钟级。

  • 怎么调试埋点? Android:adb shell setprop debug.firebase.analytics.app <package_name>;iOS:Xcode 加 -FIRAnalyticsDebugEnabled。事件会实时出现在 DebugView。

  • 要不要接 Mixpanel / Amplitude? Firebase 够用且免费;要做高级漏斗/留存/AB 测试、需要更强可视化和用户级回溯时再接 Mixpanel/Amplitude。

  • 隐私合规怎么做? GDPR/个保法要求:App 启动时不立即收集,等用户同意隐私政策后再 setAnalyticsCollectionEnabled(true);提供「拒绝追踪」开关。

错法对照

错法问题正解
在 build() 里埋事件rebuild 触发重复上报在 initState / 用户操作回调里埋
事件名带中文或动态值超过 500 个事件上限事件名固定,动态值放参数
recordError(e, s) 不带 stackTraceCrashlytics 看不到堆栈永远 catch (e, s) 两个都传
把用户手机号/邮箱直接当 user_id隐私违规用哈希后的内部 user_id
Performance trace 没 stop()数据不准用 try/finally 保证 stop 一定执行

卡点急救

  1. Analytics 数据看不到:检查 Firebase.initializeApp 是否成功;用 DebugView 验证事件是否发出。
  2. Crashlytics 堆栈是混淆后的:release 包要上传符号表。flutter build apk --split-debug-info=./symbols,然后 firebase crashlytics:symbols:upload ...。
  3. Performance 没数据:iOS 需要在 Info.plist 加 firebase_performance_collection_enabled: true;真机才能看到完整数据,模拟器有但不全。
  4. Crashlytics 不报崩溃:确认初始化在 runApp 之前;Flutter 错误已经被框架捕获(比如 red screen 在 release 是灰屏),需要 FlutterError.onError 转发。

面试常问

  • 怎么设计埋点体系? 从业务目标反推:定义北极星指标 → 拆解漏斗 → 每步一个事件 → 加维度参数(渠道、版本、人群)。事件名固定,参数做下钻。

  • Crashlytics 和 Sentry 的区别? Crashlytics 免费 + 与 Firebase 全家桶集成;Sentry 功能更强(性能、Session Replay、Source Maps 友好),按事件量计费。Flutter 项目两个都常用。

  • 怎么定位线上性能问题? Performance trace + Analytics 漏斗 + Crashlytics 用户日志(面包屑)。三者配合:漏斗定位流失步骤 → trace 看耗时分布 → 崩溃日志看异常堆栈。

  • 冷启动优化怎么做? Performance 自动监控 app_start;优化手段:减少 main() 同步初始化、延迟非必要 SDK、用 deferred component 按需加载。

自测三问

  1. 写一个埋点:用户点击「加入购物车」,参数包含商品 ID 和价格。
  2. 自定义 trace 的标准用法是什么?为什么要 try/finally?
  3. Crashlytics 中 fatal: true 和 fatal: false 的区别?

小结一句话

分析监控三件套:Analytics 看行为、Performance 看速度、Crashlytics 看崩溃;埋点设计从业务目标出发,让数据驱动迭代。

延伸

  • Firebase Analytics 文档:<https://firebase.google.com/docs/analytics>
  • Performance 监控:<https://firebase.google.com/docs/perf-mon>
  • 下一课:综合练习,把 12 课串起来做一个完整 App。
加载本节练习…
← 上一课CI/CD 与发布下一课 →综合练习