MTC Logo

Pub.dev Badge MIT License Badge Flutter Platform Badge

MTC Analytics

A lightweight, robust, and extensible Flutter package designed to simplify logging events across multiple analytics platforms simultaneously (e.g., Firebase, Amplitude, and Console).


Features

With MTC Analytics, you can:

  • ๐Ÿš€ Multi-provider dispatch: Log events to multiple analytics engines at once.
  • ๐Ÿ›ก๏ธ Fault Tolerance (Safe Logging): The service is completely fail-safe. If one tracker throws an exception (due to network drops, initialization errors, etc.), others will continue to receive events unaffected.
  • ๐Ÿ› ๏ธ Extensible architecture: Implement the simple Tracker interface to support any custom analytics provider.
  • ๐Ÿงช Test-friendly design: Features an instantiable service constructor and a reset hook to seamlessly mock analytics in your widget/unit tests.
  • ๐Ÿ“ Flexible events: Instantiate the base Event directly for quick ad-hoc event logging or subclass it for strongly-typed, reusable events.

Getting Started

Amplitude Setup

If you want to use Amplitude in iOS, make sure to add platform :ios, '10.0' (or higher) to your Podfile.

Firebase Analytics Setup

To use Firebase Analytics, you must add your application to a Firebase project using the Firebase console.


Usage

1. Initialization

Before setting user properties or tracking events, initialize the AnalyticsService with your desired list of trackers.

import 'package:mtc_analytics/mtc_analytics.dart';

void main() {
  // Initialize the analytics service with Console, Amplitude, and Firebase trackers
  AnalyticsService.instance.init([
    ConsoleTracker(),
    AmplitudeTracker(
      projectName: 'my-project-name',
      apiKey: 'amplitude-api-key',
    ),
    FirebaseTracker(),
  ]);
}

2. Set User ID & User Properties

Identify users and add segmentation properties across all configured trackers.

// Identify user
AnalyticsService.instance.setUserId('user-id-123');

// Segment user with custom properties
AnalyticsService.instance.setUserProperties({
  "name": "MTC - Flutter Team",
  "email": "team@mtc-flutter.com",
  "tier": "gold",
});

3. Log Events

A. Ad-hoc Events (Direct instantiation)

For quick, one-off events, you can instantiate the base Event class directly:

AnalyticsService.instance.track(
  Event(
    name: 'button_clicked',
    properties: {
      'button_name': 'submit',
      'screen': 'login',
    },
  ),
);

B. Structured Events (Subclassing)

For type-safe, reusable events, create a class that inherits from Event:

class PurchaseEvent extends Event {
  final String itemId;
  final double price;

  PurchaseEvent({required this.itemId, required this.price})
      : super(
          name: 'item_purchased',
          properties: {
            'item_id': itemId,
            'price': price,
          },
        );
}

// Log the structured event
AnalyticsService.instance.track(
  PurchaseEvent(itemId: 'prod_987', price: 29.99),
);

Advanced

Privacy & GDPR Compliance (Opt-Out)

You can dynamically enable or disable tracking globally, or toggle specific trackers on/off based on user consent (e.g., when they accept or reject cookies/privacy agreements).

Global Toggle

If enabled is set to false, the service will silently ignore all event tracking, user ID, and user property updates:

// Opt-out globally
AnalyticsService.instance.enabled = false;

// These calls do nothing when disabled
AnalyticsService.instance.track(Event(name: 'click'));
AnalyticsService.instance.setUserId('user-123');

Individual Tracker Toggle

You can also disable or enable tracking for a specific tracker class type:

// Disable only Firebase, keep others enabled
AnalyticsService.instance.setTrackerEnabled(FirebaseTracker, enabled: false);

// Check if a tracker is currently enabled
bool isFirebaseEnabled = AnalyticsService.instance.isTrackerEnabled(FirebaseTracker);

Creating a Custom Tracker

To integrate a new analytics platform (e.g., Mixpanel, Segment, or a custom internal API), implement the Tracker interface:

import 'package:mtc_analytics/mtc_analytics.dart';

class MyCustomTracker implements Tracker {
  @override
  void init() {
    // Initialize your third-party SDK here
  }

  @override
  void setUserId(String? userId) {
    // Associate the user id with this platform
  }

  @override
  void setUserProperties(Map<String, dynamic> properties) {
    // Set user demographics/attributes
  }

  @override
  void track(String eventName, [Map<String, Object>? properties]) {
    // Send event name and properties to your custom engine
  }
}

Mocking & Unit Testing

AnalyticsService is designed to be highly testable. You can mock tracker behavior in unit and widget tests:

import 'package:flutter_test/flutter_test.dart';
import 'package:mtc_analytics/mtc_analytics.dart';

class MockTracker implements Tracker {
  List<String> trackedEvents = [];

  @override
  void init() {}
  @override
  void setUserId(String? userId) {}
  @override
  void setUserProperties(Map<String, dynamic> properties) {}

  @override
  void track(String eventName, [Map<String, Object>? properties]) {
    trackedEvents.add(eventName);
  }
}

void main() {
  setUp(() {
    // Reset global singleton state between tests
    AnalyticsService.reset();
  });

  testWidgets('logs event when button is tapped', (tester) async {
    final mockTracker = MockTracker();
    AnalyticsService.instance.init([mockTracker]);

    // Build widget and trigger actions
    // ...

    expect(mockTracker.trackedEvents, contains('button_clicked'));
  });
}

Additional Information

Visit our official website to learn more about More Than Code (MTC).

If you like our work, you can help us with a coffee to continue creating and collaborating with the Flutter community:

Buy a coffee button

Libraries

mtc_analytics