当前位置: 首页 > news >正文

8.5 用户行为分析与埋点

数据驱动产品迭代。通过埋点收集用户行为数据,结合 Firebase Analytics 或自研统计平台,分析用户路径、转化漏斗和功能使用情况。


一、Firebase Analytics

dependencies:firebase_core:^2.30.0firebase_analytics:^10.10.0

1.1 基础事件上报

import'package:firebase_analytics/firebase_analytics.dart';classAnalyticsService{staticfinal_analytics=FirebaseAnalytics.instance;// 设置用户属性staticFuture<void>setUser(StringuserId,{String?userType})async{await_analytics.setUserId(id:userId);if(userType!=null){await_analytics.setUserProperty(name:'user_type',value:userType);}}// 页面浏览staticFuture<void>logPageView(StringpageName)async{await_analytics.logScreenView(screenName:pageName);}// 用户注册staticFuture<void>logSignUp(Stringmethod)async{await_analytics.logSignUp(signUpMethod:method);}// 用户登录staticFuture<void>logLogin(Stringmethod)async{await_analytics.logLogin(loginMethod:method);}// 搜索staticFuture<void>logSearch(Stringquery)async{await_analytics.logSearch(searchTerm:query);}// 查看商品staticFuture<void>logViewItem(Productproduct)async{await_analytics.logViewItem(currency:'CNY',value:product.price,items:[AnalyticsEventItem(itemId:product.id.toString(),itemName:product.name,itemCategory:product.category,price:product.price,),],);}// 加入购物车staticFuture<void>logAddToCart(Productproduct,int quantity)async{await_analytics.logAddToCart(currency:'CNY',value:product.price*quantity,items:[AnalyticsEventItem(itemId:product.id.toString(),itemName:product.name,price:product.price,quantity:quantity,),],);}// 下单(电商转化漏斗)staticFuture<void>logPurchase({requiredStringorderId,required double totalAmount,requiredList<Product>products,})async{await_analytics.logPurchase(transactionId:orderId,currency:'CNY',value:totalAmount,items:products.map((p)=>AnalyticsEventItem(itemId:p.id.toString(),itemName:p.name,price:p.price,)).toList(),);}// 自定义事件staticFuture<void>logCustomEvent(StringeventName,{Map<String,Object>?parameters,})async{await_analytics.logEvent(name:eventName,parameters:parameters);}}

1.2 路由自动统计(GoRouter)

classAnalyticsRouteObserverextendsNavigatorObserver{@overridevoiddidPush(Routeroute,Route?previousRoute){super.didPush(route,previousRoute);_logPageView(route);}@overridevoiddidPop(Routeroute,Route?previousRoute){super.didPop(route,previousRoute);if(previousRoute!=null)_logPageView(previousRoute);}@overridevoiddidReplace({Route?newRoute,Route?oldRoute}){super.didReplace(newRoute:newRoute,oldRoute:oldRoute);if(newRoute!=null)_logPageView(newRoute);}void_logPageView(Routeroute){finalname=route.settings.name??route.runtimeType.toString();AnalyticsService.logPageView(name);}}// 注册到 MaterialApp / GoRouterMaterialApp.router(routerConfig:router,navigatorObservers:[AnalyticsRouteObserver()],)

二、自研埋点系统

2.1 统一埋点接口

// 埋点事件模型classTrackEvent{finalStringeventName;// 事件名finalString?pageName;// 来源页面finalMap<String,dynamic>properties;// 附加属性finalDateTimetimestamp;TrackEvent({requiredthis.eventName,this.pageName,this.properties=const{},DateTime?timestamp,}):timestamp=timestamp??DateTime.now();Map<String,dynamic>toJson()=>{'event':eventName,'page':pageName,'properties':properties,'timestamp':timestamp.toIso8601String(),'app_version':AppInfo.version,'platform':Platform.operatingSystem,'device_id':DeviceInfo.deviceId,};}// 埋点 SDKclassTracker{staticfinal_queue=<TrackEvent>[];staticTimer?_flushTimer;staticconst_batchSize=20;staticconst_flushInterval=Duration(seconds:10);staticvoidinit(){// 定时刷新(批量上报)_flushTimer=Timer.periodic(_flushInterval,(_)=>_flush());}// 埋点入口staticvoidtrack(StringeventName,{String?page,Map<String,dynamic>?properties,}){finalevent=TrackEvent(eventName:eventName,pageName:page,properties:properties??{},);_queue.add(event);// 达到批量大小立即上报if(_queue.length>=_batchSize)_flush();}staticFuture<void>_flush()async{if(_queue.isEmpty)return;finalevents=List<TrackEvent>.from(_queue);_queue.clear();try{awaitAnalyticsApi.batchReport(events.map((e)=>e.toJson()).toList(),);}catch(_){// 上报失败,重新入队(下次重试)_queue.insertAll(0,events);}}staticvoiddispose(){_flushTimer?.cancel();_flush();// App 关闭前立即上报}}

2.2 声明式埋点(装饰器模式)

// 自动曝光埋点 Widget(进入视口时上报)classTrackExposureextendsStatefulWidget{finalStringeventName;finalMap<String,dynamic>?properties;finalWidgetchild;constTrackExposure({super.key,requiredthis.eventName,this.properties,requiredthis.child,});@overrideState<TrackExposure>createState()=>_TrackExposureState();}class_TrackExposureStateextendsState<TrackExposure>{bool _hasTracked=false;@overrideWidgetbuild(BuildContextcontext){returnVisibilityDetector(key:Key('track_${widget.eventName}'),onVisibilityChanged:(info){if(info.visibleFraction>0.5&&!_hasTracked){_hasTracked=true;Tracker.track(widget.eventName,properties:widget.properties);}},child:widget.child,);}}// 点击埋点 Widget(代理点击事件)classTrackTapextendsStatelessWidget{finalStringeventName;finalMap<String,dynamic>?properties;finalWidgetchild;finalVoidCallback?onTap;constTrackTap({super.key,requiredthis.eventName,this.properties,requiredthis.child,this.onTap,});@overrideWidgetbuild(BuildContextcontext){returnGestureDetector(onTap:(){Tracker.track(eventName,properties:properties);onTap?.call();},child:child,);}}// 使用TrackTap(eventName:'click_add_to_cart',properties:{'product_id':product.id,'price':product.price},onTap:_addToCart,child:ElevatedButton(onPressed:null,child:constText('加入购物车')),)TrackExposure(eventName:'view_product_card',properties:{'product_id':product.id},child:ProductCard(product:product),)

三、崩溃与性能监控

// Crashlytics 崩溃上报(配合 Firebase)import'package:firebase_crashlytics/firebase_crashlytics.dart';voidmain()async{WidgetsFlutterBinding.ensureInitialized();awaitFirebase.initializeApp();// 捕获 Flutter 框架错误FlutterError.onError=FirebaseCrashlytics.instance.recordFlutterFatalError;// 捕获异步错误(Dart Zone)awaitrunZonedGuarded(()async{runApp(constMyApp());},(error,stackTrace){FirebaseCrashlytics.instance.recordError(error,stackTrace,fatal:true);},);}// 手动上报非致命错误try{awaitriskyOperation();}catch(e,stackTrace){FirebaseCrashlytics.instance.recordError(e,stackTrace,fatal:false);}// 添加自定义日志(崩溃前的上下文)FirebaseCrashlytics.instance.log('用户点击了结算按钮');FirebaseCrashlytics.instance.setCustomKey('orderId',currentOrderId);FirebaseCrashlytics.instance.setCustomKey('userId',currentUserId);

小结

功能方案
页面统计Firebase Analytics + NavigatorObserver
电商漏斗logViewItem → logAddToCart → logPurchase
自定义埋点自研 Tracker(批量队列上报)
声明式埋点TrackTap / TrackExposure 装饰器
崩溃监控Firebase Crashlytics
性能监控Firebase Performance

👉 下一节继续阅读后续章节

http://www.jsqmd.com/news/642820/

相关文章:

  • SQL如何实现分组汇总结果的二次加工_使用子查询或CTE
  • 哔哩下载姬DownKyi:3步掌握B站视频高效管理的终极指南
  • 仿真学习系列(五十一):ADS仿真理解电容特性
  • Advanced R与C++集成:Rcpp实战教程提升代码性能
  • 工业现场为什么离不开它:矿浆浆液管道工程的设计、安装与运维
  • [整流与稳压] 【每周分享】说一说圣邦微DCDC芯片SGM61410
  • Flutter权限请求别再弹窗就完事了!聊聊permission_handler在用户体验上的那些高级操作
  • NAVIGATION及NAVIGATOR的使用4
  • 如何快速提升macOS多任务效率:Topit窗口置顶工具完整指南
  • 告别Qt调试器报错:一份详细的CDB配置避坑指南与原理浅析
  • beberlei/assert异常处理机制:从基础到高级的错误管理策略
  • 别等环保检查来了才着急:大气污染防治工程的系统逻辑与落地要点
  • 终极指南:如何安全使用R3nzSkin实现英雄联盟换肤体验
  • Oracle 19c RAC安装避坑指南:HAIP禁用与ASM实例启动失败的深度解析
  • 决策树与深度学习的融合:神经网络支持的决策树深度解析
  • goland 语言--数组
  • *8发散创新:基于Python的本体推理与知识表示实战应用**在人工智能和语义网
  • 数据分析方向毕业设计精选选题推荐【热门研究方向创新选题】2026
  • 优化IDEA堆内存配置以提升多线程应用性能
  • **刚体模拟的编程实践:用C++实现高效物理引擎中的碰撞检测与响应**在游戏开发、动画制作和
  • Qwen3-ASR-1.7B高精度ASR部署教程:对比0.6B版本,精度/显存/速度实测分析
  • node.js彩信接口如何集成?使用Node.js异步流模式发送多图片彩信
  • 配置node.js环境
  • SDMatte+模型详解:为何复杂边缘更准?权重结构与推理优化点解析
  • 避坑指南:在华为ENSP中配置多区域OSPF时,我踩过的那些‘坑’(含Stub区域、路由聚合、认证配置)
  • 放射科医生AI转型倒计时:2026奇点大会人才能力图谱发布——你的岗位未来18个月将被替代/增强/重构?立即测算你的不可替代指数
  • 投稿 IEEE Transactions overleaf 模板; Cover Letter模板;SCI论文投稿格式问题会直接拒稿吗; IEEE Transactions 投稿全流程状态
  • 从数据监测到训练优化:视觉训练 APP 的硬件联动逻辑
  • 【计组核心考点精讲】从模拟题看计算机组成原理期末复习策略
  • Go语言数组底层结构详解