Flutter SDK
A lightweight Flutter SDK with full cross-platform support.
Requirements
- Flutter 3.10+
- Dart 3.0+
Platform Support
| Platform | Supported |
|---|---|
| iOS | Yes |
| Android | Yes |
| Web | Yes |
| macOS | Yes |
| Windows | Yes |
| Linux | Yes |
Installation
Add to your pubspec.yaml:
dependencies:
mostly_good_metrics_flutter: ^0.3.0
Then run:
flutter pub get
Quick Start
Initialize
Initialize once at app startup (typically in main.dart):
import 'package:flutter/material.dart';
import 'package:mostly_good_metrics_flutter/mostly_good_metrics_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await MostlyGoodMetrics.configure(
MGMConfiguration(apiKey: 'mgm_proj_your_api_key'),
);
runApp(MyApp());
}
Track Events
// Simple event
MostlyGoodMetrics.track('button_clicked');
// Event with properties
MostlyGoodMetrics.track('purchase_completed', properties: {
'product_id': 'SKU123',
'price': 29.99,
'currency': 'USD',
});
Identify Users
// Set user identity
await MostlyGoodMetrics.identify('user_123');
// Reset identity (e.g., on logout)
await MostlyGoodMetrics.resetIdentity();
Configuration Options
await MostlyGoodMetrics.configure(
MGMConfiguration(
apiKey: 'mgm_proj_your_api_key',
baseUrl: 'https://ingest.mostlygoodmetrics.com',
environment: 'production',
appVersion: '1.0.0',
maxBatchSize: 100,
flushInterval: 30,
maxStoredEvents: 10000,
enableDebugLogging: kDebugMode,
trackAppLifecycleEvents: true,
),
);
| Option | Default | Description |
|---|---|---|
apiKey | Required | Your API key |
baseUrl | https://ingest.mostlygoodmetrics.com | API endpoint |
environment | "production" | Environment name |
appVersion | - | App version (required for install/update tracking) |
maxBatchSize | 100 | Events per batch |
flushInterval | 30 | Auto-flush interval in seconds |
maxStoredEvents | 10000 | Max cached events |
enableDebugLogging | false | Enable debug output |
trackAppLifecycleEvents | true | Auto-track lifecycle events |
optedOutByDefault | false | Start opted out until optIn() is called (Privacy) |
collectDeviceProperties | true | Collect device manufacturer, locale, timezone |
Automatic Events
| Event | When | Properties |
|---|---|---|
$app_installed | First launch after install | - |
$app_updated | First launch after version change | previous_version, current_version |
$app_opened | App started | - |
$app_foregrounded | App became active | - |
$app_backgrounded | App went to background | - |
Session Management
// Start a new session manually
await MostlyGoodMetrics.startNewSession();
// Access current session ID
final sessionId = MostlyGoodMetrics.sessionId;
Privacy
The SDK never collects advertising identifiers (IDFA/GAID), precise location, contacts, or any other personal data you don't explicitly pass to track() or identify(). identify() is entirely optional — without it, users are tracked under a random anonymous ID ($anon_...) generated by the SDK, not derived from the device.
Opt-out
// Stop all tracking immediately. track(), identify(), and flush() become
// no-ops, and any queued (unsent) events are deleted. The choice is
// persisted and survives app restarts.
await MostlyGoodMetrics.optOut();
// Check the current state
final optedOut = MostlyGoodMetrics.isOptedOut;
// Resume tracking (also persisted)
await MostlyGoodMetrics.optIn();
For consent-first apps (e.g. GDPR), start opted out and only opt in after consent:
await MostlyGoodMetrics.configure(
MGMConfiguration(
apiKey: 'mgm_proj_your_api_key',
optedOutByDefault: true,
),
);
// Later, once the user consents:
await MostlyGoodMetrics.optIn();
A persisted opt-in/opt-out choice always takes precedence over optedOutByDefault.
Rotating the anonymous ID
Generate a fresh anonymous ID so future events can't be linked to earlier anonymous activity:
await MostlyGoodMetrics.resetAnonymousId();
Forget me
For a complete local reset (e.g. a user deletes their account):
await MostlyGoodMetrics.resetIdentity(clearAnonymousId: true);
This clears the user ID, rotates the anonymous ID, deletes all pending (unsent) events, clears super properties and sticky local experiment assignments, and starts a new session.
Limiting device properties
await MostlyGoodMetrics.configure(
MGMConfiguration(
apiKey: 'mgm_proj_your_api_key',
collectDeviceProperties: false,
),
);
When disabled, events omit device manufacturer, locale, and timezone. Platform, OS version, and app version are still included.
Error Handling
try {
MostlyGoodMetrics.track('invalid-event-name');
} on MGMError catch (e) {
print('Error type: ${e.type}');
print('Message: ${e.message}');
}
Error types:
MGMErrorType.notConfigured- SDK not configuredMGMErrorType.invalidEventName- Invalid event nameMGMErrorType.invalidProperties- Invalid propertiesMGMErrorType.networkError- Network failureMGMErrorType.rateLimited- API rate limited
Manual Flush
await MostlyGoodMetrics.flush();
// Check pending events
final count = await MostlyGoodMetrics.getPendingEventCount();
print('$count events pending');
// Clear pending events
await MostlyGoodMetrics.clearPendingEvents();