如何在 Flutter 中设置 Firebase Analytics 自定义事件,而不在每个屏幕中传递“分析/观察者”对象

Posted

技术标签:

【中文标题】如何在 Flutter 中设置 Firebase Analytics 自定义事件,而不在每个屏幕中传递“分析/观察者”对象【英文标题】:How to set Firebase Analytics custom events in Flutter without passing 'analytics/observer' object in each screen 【发布时间】:2019-11-22 00:48:42 【问题描述】:

我正在为我的 Flutter 项目设置 Firebase Analytics Package。库中提供的sample 传递analytics 对象用于跟踪事件,observer 用于跟踪选项卡更改。

class MyApp extends StatelessWidget 
 ...
Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Firebase Analytics Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      navigatorObservers: <NavigatorObserver>[observer],
      home: MyHomePage(
        title: 'Firebase Analytics Demo',
        analytics: analytics,
        observer: observer,
      ),
    );
  


...

class _MyHomePageState extends State<MyHomePage> 
...
Future<void> _sendAnalyticsEvent() async 
    await analytics.logEvent(
      name: 'test_event',
      parameters: <String, dynamic>
        'string': 'string',
        'int': 42,
        'long': 12345678910,
        'double': 42.0,
        'bool': true,
      ,
    );
    setMessage('logEvent succeeded');
  
...

我的应用由许多屏幕组成,其中状态通过Bloc 包进行管理。将这些对象从mainScreen 一直传递到事件发生的树上并不好。

有没有办法在不将它们传递给小部件树的情况下访问它们。或者如果我创建一个 FirebaseAnalytics 类的新对象并使用生成的对象来设置事件,它会起作用吗?

static FirebaseAnalytics analytics = FirebaseAnalytics();

或者我应该使用 Flutter_Bloc 作为记录和设置 Flutter 事件的中心位置?

【问题讨论】:

【参考方案1】:

您可以使用provider 包在您的小部件树中“提供”您的分析和观察者。

class MyApp extends StatelessWidget 
  static FirebaseAnalytics analytics = FirebaseAnalytics();
  static FirebaseAnalyticsObserver observer =
      FirebaseAnalyticsObserver(analytics: analytics);

  @override
  Widget build(BuildContext context) 
    return MultiProvider(
        providers: [
            Provider<FirebaseAnalytics>.value(value: analytics),
            Provider<FirebaseAnalyticsObserver>.value(value: observer),
        ],
        child: MaterialApp(
            title: 'Firebase Analytics Demo',
            theme: ThemeData(
                primarySwatch: Colors.blue,
            ),
            navigatorObservers: <NavigatorObserver>[observer],
            home: MyHomePage(
                title: 'Firebase Analytics Demo',
            ),
        ),
    ); 
  

然后在您的任何子小部件中...

Future<void> _sendAnalyticsEvent() async 
    FirebaseAnalytics analytics = Provider.of<FirebaseAnalytics>(context);
    await analytics.logEvent(
      name: 'test_event',
      parameters: <String, dynamic>
        'string': 'string',
        'int': 42,
        'long': 12345678910,
        'double': 42.0,
        'bool': true,
      ,
    );
    setMessage('logEvent succeeded');
  

现在您无需将 Firebase 实例传递给小部件构造函数。

【讨论】:

使用flutter_bloc 是否MultiProvider()MultiBlocProvider() 有关系吗?【参考方案2】:

除了使用provider 或带有静态参数的全局类之外,另一种选择是将services 与GetIt 包一起使用。

只需创建一个包含analyticsobserver 的类。例如。像这样:

class AnalyticsService 
  final FirebaseAnalytics _analytics = FirebaseAnalytics();

  FirebaseAnalyticsObserver getAnalyticsObserver() => FirebaseAnalyticsObserver(analytics: _analytics);

  Future logScreens(@required String name) async 
    await _analytics.setCurrentScreen(screenName: name);
  

  ... // implement the events you want to track

现在创建一个locator 并将该类注册为一个惰性singleton

GetIt locator = GetIt.instance;

setupServiceLocator() 
  locator.registerLazySingleton<AnalyticsService>(() => AnalyticsService());

使locator 可访问:

void main() async 
  WidgetsFlutterBinding.ensureInitialized();
  setupServiceLocator();
  runApp(MyApp());

现在,您可以通过调用locator 从应用中的任何位置访问service。 例如:

return MaterialApp(
  debugShowCheckedModeBanner: false,
  title: 'Demo',
  theme: themeData,
  initialRoute: SplashScreen.id,
  routes: routes,
  navigatorObservers: [
    // Access the observer
    locator<AnalyticsService>().getAnalyticsObserver(),
  ],
);

 onTap: () 
   locator<AnalyticsService>().logScreens(name: DetailsScreen.id);
 

【讨论】:

嘿,你能给我一个演示项目吗?因为我不知道我想尝试这样做,但无法弄清楚,如果举个例子,谢谢 嘿@AlwayssBijoy,这里有一个很好的解释和上面代码的来源:filledstacks.com/post/firebase-analytics-and-metrics-in-flutter 谢谢!由于我已经拥有 GetIt,这正是我最终要做的。 我喜欢 getIt 因为我正在使用 MultiBlocProvidor。而且我也在 getIt 中使用 audio_service【参考方案3】:

也可以创建一个包含所有全局实例的文件。例如: 文件:lib 目录中的 globals.dart

文件内容:

class Global 
    static final FirebaseAnalytics analytics = FirebaseAnalytics();

然后使用它:

Global.analytics.logEvent(...)

【讨论】:

最简单最简单的。 provider、getit、block 其余的都是骗人的

以上是关于如何在 Flutter 中设置 Firebase Analytics 自定义事件,而不在每个屏幕中传递“分析/观察者”对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter Web 项目中设置 Firebase 功能

如何在 Flutter 中设置 Firebase Analytics 自定义事件,而不在每个屏幕中传递“分析/观察者”对象

如何在 Flutter 中设置闹钟?

如何在 Xcode 中设置 Flutter 构建选项

如何在firebase实时数据库规则中设置变量

如何在 Flutter 中设置主屏幕的背景颜色?