Practical advice when using Firebase Analytics in Flutter development
Getting up and running with Firebase Analytics for Flutter is pretty simple and is well described in the documentation, so I won’t repeat it all here. Once your project is setup the code to track page views is as simple as:
FirebaseAnalytics analytics = FirebaseAnalytics();
MaterialApp(
home: MyAppHome(),
navigatorObservers: [
FirebaseAnalyticsObserver(analytics: analytics),
],
);
Simple right, so what’s the problem? Well, the problem is if you navigate using anything like these approaches, then you won’t actually see any screen_view
events in your dashboard:
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MyPage()),
);
}
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => MyPage()),
);
}
So why is that? What’s the problem? In short, the problem is that these are not named routes. The reason this is a problem you can see by looking at the implementation of FirebaseAnalyticsObserver
:
String defaultNameExtractor(RouteSettings settings) => settings.name;
class FirebaseAnalyticsObserver extends RouteObserver<PageRoute<dynamic>> {
FirebaseAnalyticsObserver({
@required this.analytics,
this.nameExtractor = defaultNameExtractor,
Function(PlatformException error) onError,
}) : _onError = onError;
void _sendScreenView(PageRoute<dynamic> route) {
final String screenName = nameExtractor(route.settings);
if (screenName != null) {
analytics.setCurrentScreen(screenName: screenName).catchError(
(Object error) {
if (_onError == null) {
debugPrint('$FirebaseAnalyticsObserver: $error');
} else {
_onError(error);
}
},
test: (Object error) => error is PlatformException,
);
}
}
FirebaseAnalyticsObserver
calls _sendScreenView
for each navigation and uses the defaultNameExtractor
to determine the screen name. If that resolves to null
, then no event gets logged. The defaultNameExtractor
just uses the name
property of the supplied RouteSettings
. And this is the problem; in the navigation examples I gave above there are no RouteSettings
, so the screenName
ends up as null
and nothings gets logged.
Thankfully, the solution is pretty simple. Either use named routes when navigating, or supply a RouteSettings
instance with your navigation such as:
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MyPage(),
settings: RouteSettings(name: 'MyPage'),
),
);
}
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => MyPage().
settings: RouteSettings(name: 'MyPage'),
),
);
}
If you want to see the events in Firebase Console quickly and reliably while debugging, use DebugView.
To enable Analytics Debug mode on an Android device, execute the following command line:
adb shell setprop debug.firebase.analytics.app <package_name>
This behavior persists until you explicitly disable Debug mode by executing the following command line:
adb shell setprop debug.firebase.analytics.app .none.
To enable Analytics Debug mode on your development device, specify the following command line argument in Xcode :
-FIRDebugEnabled
This behavior persists until you explicitly disable Debug mode by specifying the following command line argument:
-FIRDebugDisabled
Note: Before using DebugView, you should ensure that your device time is accurate. A skewed device clock will result in delayed or missing events in your Analytics reports.
For more information about using Firebase, check out the docs on flutter.dev.
#firebase #flutter #mobile-apps