App Monitoring
ShipFlutter includes a complete monitoring setup using:
- Firebase Google Analytics for user behavior
- Performance Monitoring for app performance
- Firebase Crashlytics for crash reporting
The monitoring module is privacy-focused and requires explicit user consent before collecting any data.
Setup
Enable and setup each service in the Firebase Console:
User Consent
All monitoring features require explicit user consent. The consent system includes:
class UserConsent { bool analyticsStorage; // Basic analytics bool adUserData; // User data for ads bool adPersonalization; // Personalized ads bool adStorage; // Ad storage bool functionalityStorage; // App functionality bool personalizationStorage; // Personalization bool securityStorage; // Security features bool errorsData; // Error reporting}
Analytics Service
The MonitoringService
handles analytics, performance monitoring, and crash reporting:
// Log custom eventawait monitoringService.instance.logEvent( 'button_click', parameters: {'button_id': 'submit'},);
// Log purchaseawait monitoringService.instance.logPurchase( currency: 'USD', value: 9.99, items: ['premium'],);
// Track operation performancefinal trace = await monitoringService.instance.newTrace('data_fetch');
try { await trace.start(); // Perform operation await fetchData();} finally { await trace.stop();}
try { // Your code} catch (error, stack) { // Log error to Crashlytics await monitoringService.instance.recordError( error, stack, reason: 'Data fetch failed', );}
// Set user propertiesawait monitoringService.instance.setUserProperty( 'subscription_type', 'premium',);
// Get analytics IDfinal id = await monitoringService.instance.getAnalyticsId();
Route Tracking
The AnalyticsRouteObserver
automatically tracks screen views and its already added
in the navigator:
class AnalyticsRouteObserver extends RouteObserver<ModalRoute<dynamic>> { @override void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) { if (route.settings.name != null) { monitoringService.instance.logEvent(route.settings.name!); } }}
Consent Management
The consent flow is managed by the ConsentController
:
-
Check for existing consent:
final hasConsent = await monitoringService.instance.hasUserConsent(); -
Show consent banner if needed:
if (!hasConsent) {showConsentBanner(context);} -
Update consent settings:
await monitoringService.instance.setUserConsent(UserConsent(analyticsStorage: true,errorsData: true,),); -
Features are enabled based on consent:
final consent = await monitoringService.instance.getUserConsent();if (consent.analyticsStorage) {// Enable Analytics}