如何在不在每个屏幕中传递 'analytics/observer' 对象的情况下在 Flutter 中设置 Firebase Analytics 自定义事件
How to set Firebase Analytics custom events in Flutter without passing 'analytics/observer' object in each screen
我正在设置 Firebase Analytics Package for my Flutter project. The 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
一直传递到事件发生的树下并不是一件好事。
有没有一种方法可以访问它们而无需在小部件树周围传递它们。或者,如果我创建一个 class FirebaseAnalytics
的新对象并使用生成的对象设置事件,它会起作用吗?
static FirebaseAnalytics analytics = FirebaseAnalytics();
或者我应该使用 Flutter_Bloc 作为记录和设置我的 Flutter 事件的中心位置吗?
您可以使用 provider
包来 'provide' 您的分析和观察者在您的小部件树下。
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 实例传递给小部件构造函数。
也可以创建一个包含所有全局实例的文件。例如:
文件:globals.dart 在您的 lib 目录中。
文件内容:
class Global {
static final FirebaseAnalytics analytics = FirebaseAnalytics();
}
然后使用它:
Global.analytics.logEvent(...)
除了使用 provider or a global class with static parameters, another option is to use services
with the GetIt 包。
只需创建一个包含 analytics
和 observer
的 class。例如。像这样:
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
并将 class 注册为惰性 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);
}
我正在设置 Firebase Analytics Package for my Flutter project. The 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
一直传递到事件发生的树下并不是一件好事。
有没有一种方法可以访问它们而无需在小部件树周围传递它们。或者,如果我创建一个 class FirebaseAnalytics
的新对象并使用生成的对象设置事件,它会起作用吗?
static FirebaseAnalytics analytics = FirebaseAnalytics();
或者我应该使用 Flutter_Bloc 作为记录和设置我的 Flutter 事件的中心位置吗?
您可以使用 provider
包来 'provide' 您的分析和观察者在您的小部件树下。
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 实例传递给小部件构造函数。
也可以创建一个包含所有全局实例的文件。例如: 文件:globals.dart 在您的 lib 目录中。
文件内容:
class Global {
static final FirebaseAnalytics analytics = FirebaseAnalytics();
}
然后使用它:
Global.analytics.logEvent(...)
除了使用 provider or a global class with static parameters, another option is to use services
with the GetIt 包。
只需创建一个包含 analytics
和 observer
的 class。例如。像这样:
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
并将 class 注册为惰性 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);
}