Skip to content
Docs

Mobile

Flutter plugin

This page is assembled from sdks/flutter/README.md in the repository. See the SDK overview for the choice between native SDKs and wrappers.

Formerly dtrackier_flutter. Until 2.0 the deprecated DTrackier typedef forwards to Metrixed; change the dependency and import to package:metrixed_flutter/metrixed_flutter.dart.

metrixed_flutter is a thin plugin over the native Android and iOS SDKs. All tracking logic (offline queue, request signing, attribution, SKAdNetwork, consent enforcement) lives in the native SDKs; the plugin validates arguments and forwards them over a MethodChannel / EventChannel. Method names mirror the native SDKs. Android min API 21, iOS 13.

Install

yaml
dependencies:
  metrixed_flutter: ^1.0.0

Android resolves com.metrixed:metrixed-android from Maven Central (until published, add the Maven-layout repo from make sdk-android-build to your root build.gradle). iOS pulls the Metrixed pod through the plugin podspec.

Platform setup is the same as for the native SDKs:

  • Android: a VIEW intent filter for your scheme / App Links on the main activity; kids apps also add <uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove" />.
  • iOS: NSUserTrackingUsageDescription, SKAdNetworkItems, NSAdvertisingAttributionReportEndpoint, Associated Domains applinks:go.yourdomain.com, URL scheme (see the iOS README). Flutter forwards open url and Universal Links to the SDK through the plugin's application-delegate hooks.

Initialise

dart
import 'package:metrixed_flutter/metrixed_flutter.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Metrixed.initialize(const DTConfig(
    appToken: 'APP_TOKEN',
    environment: DTEnvironment.production,   // sandbox: flagged on every payload, excluded from billing
    baseUrl: 'https://ingest.example.com',
    secret: 'SDK_SECRET',                    // request signing
  ));
  runApp(const MyApp());
}

Dart starts after the first Android activity is visible: the install is reported immediately but the very first session starts at the next foreground. To count it too, initialise the native SDK in Application.onCreate instead of calling initialize.

Platform-specific options are ignored on the other platform: secretId, consentRequired, collectGaid, collectAppSetId, collectAndroidId, oaid, preloadKey, referrerTimeoutMs (Android); trackingBaseUrl, attWaitInterval, readIdfa, readIdfv, linkMe*, skanEnabled, storeKitForwarding (iOS). kidsMode maps to setKidsMode / coppaCompliant.

Events and ad revenue

dart
Metrixed.trackEvent(const DTEvent('level_up', callbackParams: {'level': '5'}));
Metrixed.trackEvent(DTEvent('purchase', revenue: 9.99, currency: 'USD', dedupeId: orderId, partnerParams: {'af_content': 'x'}));
Metrixed.trackAdRevenue(const DTAdRevenue('applovin_max', revenue: 0.012, currency: 'USD', adUnit: 'u1', adType: 'rewarded'));
Metrixed.setCustomerUserId('user-42');

Revenue is a number plus an ISO currency (required together), formatted by the native SDK as a 6-decimal string. Invalid arguments throw ArgumentError before anything reaches native code. Ad revenue: call trackAdRevenue from your mediation callback (MAX ad.revenue / networkName, LevelPlay impressionData.revenue, AdMob valueMicros / 1e6 with currencyCode).

dart
Metrixed.setDeeplinkHandler((link) => router.go(link.deepLinkValue ?? link.url));   // or: Metrixed.deeplinks.listen(...)
await Metrixed.processDeeplink(url);   // links you receive yourself

Direct (scheme / App Link / Universal Link) and deferred links arrive as DTDeeplink(url, source, clickId, deepLinkValue, params). Links that arrive before the first listener are held natively and delivered on subscribe. Android handles onNewIntent and the launching intent itself.

dart
Metrixed.setConsent(const DTConsent(thirdPartySharing: false, measurement: true, adPersonalization: false, gdprApplies: true, tcf: tcString));
Metrixed.setThirdPartySharing(false);
Metrixed.gdprForgetMe();   // server erase + local wipe; the SDK stays off afterwards

tcf, gpp, googleDma, metaLdu are honoured on iOS; Android carries thirdPartySharing, measurement, adPersonalization, gdprApplies. setPushToken takes the FCM token (Android) or the hex APNs token (iOS).

Platform differences

CallAndroidiOS
setExternalDeviceIdyesset externalDeviceId in DTConfig (call is a no-op)
setEnabled, setOfflineMode, setSecretyesno-op
getAttribution, attributions / setAttributionListeneryesnull / never fires

Tests and CI

make sdk-flutter-test (not part of make test), in the pinned Flutter 3.24.5 image: flutter analyze, Dart tests with a mocked channel and the shared wire vectors (sdks/test-vectors/wrapper-api.json), flutter pub publish --dry-run validation, and a debug APK build of example/ which compiles the Kotlin bridge against the real AAR. The iOS side builds in the macOS job of .github/workflows/sdk-wrappers.yml. Request signing is done and tested by the native SDKs.

Sample: example/. Changelog: CHANGELOG.md.