如何在Flutter中设置Firebase Analytics自定义事件,而无需在每个屏幕中传递“ analytics / observer”对象

时间:2019-07-12 09:10:18

标签: firebase flutter google-analytics firebase-analytics bloc

我正在为我的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事件的中心位置?

3 个答案:

答案 0 :(得分:3)

还可以使用所有全局实例创建文件。例如: 文件: lib 目录中的 globals.dart

文件内容:

class Global {
    static final FirebaseAnalytics analytics = FirebaseAnalytics();
}

然后使用它:

Global.analytics.logEvent(...)

答案 1 :(得分: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实例传递给小部件构造函数。

答案 2 :(得分:1)

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

只需创建一个包含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());
}

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

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);
 }