如何使用Firebase Analytics跟踪Android Fragments

58

在我的安卓应用中,我有一个 Activity,其中包含 3 或 4 个片段,这些片段可以根据一些用户或服务器事件依次连接。

我想将所有这些片段作为屏幕在 Firebase 中进行跟踪。

因此,如果可能的话,是否有一个 API 可以在片段的 onCreate 中调用,并告诉 Firebase 用户当前正在 fragment1、fragment2 或 fragment3 中?

4个回答

87

更新

由于setCurrentScreen已经被弃用,您可以使用logEvent方法。

Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.SCREEN_NAME, fragment.getClass().getSimpleName());
bundle.putString(FirebaseAnalytics.Param.SCREEN_CLASS, fragment.getClass().getSimpleName());
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle);

我使用以下adb命令来检查是否一切正常。

adb shell setprop log.tag.FA VERBOSE
adb shell setprop log.tag.FA-SVC VERBOSE
adb logcat -v time -s FA FA-SVC

执行此操作后,您将在logcat中看到screen_view事件。就像这个:

10-15 13:14:13.744 V/FA-SVC (20323): Logging event: origin=app,name=screen_view(_vs),params=Bundle[{ga_event_origin(_o)=app, engagement_time_msec(_et)=31600, ga_previous_class(_pc)=ContentsFragment, ga_previous_id(_pi)=8077407744361472421, ga_previous_screen(_pn)=ContentsFragment, ga_screen_class(_sc)=TestFragment, ga_screen_id(_si)=8077407744361472423, ga_screen(_sn)=TestFragment}]

有一个特殊的方法可以设置当前屏幕 - setCurrentScreen

我是这样使用它的:

mFirebaseAnalytics.setCurrentScreen(this, fragment.getClass().getSimpleName(), fragment.getClass().getSimpleName());

一旦调用该方法,LogCat中会出现以下消息:

Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=HomeFragment, firebase_previous_id(_pi)=4121566113087629222, firebase_previous_screen(_pn)=HomeFragment, firebase_screen_class(_sc)=StatisticsFragment, firebase_screen_id(_si)=4121566113087629223, firebase_screen(_sn)=StatisticsFragment}]

自动活动跟踪中出现以下事件:

Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=StatisticsFragment, firebase_previous_id(_pi)=4121566113087629223, firebase_previous_screen(_pn)=StatisticsFragment, firebase_screen_class(_sc)=LoginActivity, firebase_screen_id(_si)=4121566113087629224}]

正如您所见,它们几乎相同,所以 setCurrentScreen 正常工作。

我只能在第二天在 Firebase 控制台中看到这些类。这对于 Firebase 来说是正常的-处理这些数据需要时间。

Firebase 控制台


3
你认为在哪个方法中调用这个方法最好?是在onStartonResume还是其他方法中?(在一个片段中) - Thomas Vos
6
我认为onResume是最好的选择,因为当你从另一个片段返回时,它会被调用。 - Artem Mostyaev
1
请看以下有关编程的文本内容:https://firebase.google.com/docs/analytics/debugview https://support.google.com/firebase/answer/7201382?hl=en&utm_id=ad&authuser=0 - yozhik
@Charan 活动会自动进行跟踪,这些事件的顺序取决于您在活动生命周期中调用 setCurrentScreen 的时间。 - Artem Mostyaev
2
setCurrentScreen 已经过时了 :( - Kartik Garasia
显示剩余4条评论

13

在Artem Mostyaev的回答中,我希望能够增加更多深入的见解。GA/Firebase面板在DEV版本中反映出了类名,但在PROD版本中没有反映出来。这里的主要罪魁祸首是

fragment.getClass().getSimpleName()

在生产环境中,我们对片段名称进行了混淆。因此,GA/Firebase 显示的类名会像 (a,b,ah 等)。

在其他情况下使用getSimpleName()也是危险的。

更多资料: https://medium.com/@elye.project/the-danger-of-using-class-getsimplename-as-tag-for-fragment-5cdf3a35bfe2

Proguard 规则

-keepnames class com.somepackage.yourclass 

1
或者您可以使用此Proguard规则来保留所有片段:-keepnames class * extends androidx.fragment.app.Fragment - mindw0rk

13

由于 setCurrentScreen 已经弃用,您可以使用 firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle) 代替。

这里有一篇博客文章here,详细解释了如何手动跟踪屏幕。

以下是一个例子:

private fun setCurrentScreen(screenName: String) = firebaseAnalytics?.run {
    val bundle = Bundle()
    bundle.putString(FirebaseAnalytics.Param.SCREEN_NAME, screenName)
    bundle.putString(FirebaseAnalytics.Param.SCREEN_CLASS, this@BaseFragment.javaClass.simpleName)
    logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle)
}

此外,如果您想要自动跟踪屏幕,则可以在其中一个BaseFragment生命周期方法(如onResume)中调用此函数。请注意,有些片段可能不必更改当前屏幕,例如那些在ViewPager中创建的片段,因此我声明了一个open val,您可以override以更改默认行为。
以下是BaseFragment中的代码:
protected open val trackScreenView: Boolean = true

override fun onResume() {
    super.onResume()

    if (trackScreenView) setCurrentScreen(this.javaClass.simpleName)
}

你可以通过在目标Fragment中覆盖它来禁用它:

override val trackScreenView: Boolean = false

顺便提一下,如果您正在使用NavigationUI组件,则目前没有自动跟踪屏幕的解决方案,它只会跟踪您拥有的单个活动,因此您可以通过在应用程序清单中添加此meta-data来防止Firebase自动屏幕报告:
<application
    android:name=".App"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    
    <!-- .... -->
    
    <meta-data
        android:name="google_analytics_automatic_screen_reporting_enabled"
        android:value="false" />
</application>

9
对于使用了 NavigationUI 的项目,您可以使用监听器 NavController.OnDestinationChangedListeneronCreate() 内部。
override fun onCreate() {
      super.onCreate()
      .
      .
      .
      .
      navController = Navigation.findNavController(context!!, R.id.nav_host_fragment)
      navController?.addOnDestinationChangedListener(listener)
}

在这3个监听函数参数中,

  • controller 用于获取类名信息。
  • destination 用于获取目标布局 XML 名称字符串,可以通过 android:label 属性在 nav_host_fragment 中找到。
private val listener = NavController.OnDestinationChangedListener { controller, destination, arguments ->
      
      val bundle = Bundle()
      val currentFragmentClassName = (controller.currentDestination as FragmentNavigator.Destination).className
      bundle.putString(FirebaseAnalytics.Param.SCREEN_NAME, destination.label.toString())
      bundle.putString(FirebaseAnalytics.Param.SCREEN_CLASS, currentFragmentClassName)
      FirebaseAnalytics.getInstance(requireContext()).logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle)
      
}

不要忘记清理

override fun onDestroy() {
      super.onDestroy()
      navController?.removeOnDestinationChangedListener(listener)
}

好的方法,这是一个非常干净的做法! - OhhhThatVarun
干净的方法,但我假设如果您使用Proguard,名称将被混淆? - km11

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接