Implement mix-panel in a flutter app
What is mix-panel for?
You can see more examples and better explanations in the video below, but to make long story short, it is a tracking tool.
Why do I need a tracking tool?
May you don’t but I’m pretty sure that your business or the company you are working for needs to have implemented a tracker tool by yesterday
Using a tracking tool you can follow your customer’s behaviors.
Which features do they use more?
Why they don’t complete some flows?
Which products do your customers visit more?
For what?
To send them targeted promotions
To assist and engage them
To improve your features
To enhance your design
There are many use cases, but you will be able to make better decisions about your next steps in tech and marketing.
Important!
Pricing (Free Up to 20 million monthly events)
Yes, it’s a payment tool, but I think it’s enough for now 20 million monthly for free ;-)
Video Info
https://www.youtube.com/watch?v=oAxB4kY_G_o
Hands to code!
Step 1
Create your account or login
Step 2
Get your token Id
Properties → Project Settings → Scroll down until you find [Access Keys] and copy the token ID
Step 3
install the library (https://pub.dev/packages/mixpanel_flutter/install)
flutter pub add mixpanel_flutter
Step 4
Create your implementation MixpanelService
import 'package:flutter/material.dart';
import 'package:mixpanel_flutter/mixpanel_flutter.dart';
class MixPanelService {
static const mixpanelToken = ''; // paste here your token ID
static Mixpanel? _instance;
static Future<Mixpanel> init() async {
// ignore: prefer_conditional_assignment
if (_instance == null) {
_instance = await Mixpanel.init(
mixpanelToken,
optOutTrackingDefault: false,
trackAutomaticEvents: true,
);
}
return _instance!;
}
Future<void> openApp() async {
// you should call this method when the app starts
// this id its a random ID, but dont worry we will set a better ID after the user sign in or sign up
debugPrint('openApp');
String distinctId = await _instance!.getDistinctId();
_instance!.identify(distinctId);
_instance!.track('App_open');
}
Future<void> changeIdentify({
required String newUserIdentity,
required String userId,
required String userName,
required String email,
required String country,
required String city,
}) async {
debugPrint('changeIdentify');
// change the random user ID for our custom user identifier
// so you will be able to check fnoceda83 profile in this case
_instance!.identify(newUserIdentity);
// all of these properties you will be able to check on the user profile inside mixpanel
_instance!.getPeople().set('\$name', userName);
_instance!.getPeople().set('\$email', email);
_instance!.getPeople().set('Business Country', country);
_instance!.getPeople().set('Business City', city);
// this properties will be available in each event, you can add a lot
_instance!.registerSuperProperties({
'userId': userId,
});
}
//events
signInEvent({required String userName}) {
debugPrint('signInEvent');
_instance!.track(
'signInEvent',
properties: {'userName': userName, 'datetime': DateTime.now().toUtc()},
);
}
signUpEvent({
required String userName,
required String email,
required String country,
required String city,
}) {
debugPrint('signUpEvent');
_instance!.track('signUpEvent', properties: {
'userName': userName,
'email': email,
'country': country,
'city': city,
'datetime': DateTime.now().toUtc()
});
}
showHomePageEvent({required String userName}) {
debugPrint('showHomePageEvent');
_instance!.track(
'showHomePageEvent',
properties: {'userName': userName, 'datetime': DateTime.now().toUtc()},
);
}
visitProductEvent({
required String userName,
required String produtId,
}) {
debugPrint('visitProductEvent');
_instance!.track(
'visitProductEvent',
properties: {
'userName': userName,
'produtId': produtId,
'datetime': DateTime.now().toUtc()
},
);
}
buyProductEvent({
required String userName,
required String produtId,
}) {
debugPrint('buyProductEvent');
_instance!.track(
'buyProductEvent',
properties: {
'userName': userName,
'produtId': produtId,
'datetime': DateTime.now().toUtc()
},
);
}
}
Step 5
Use it
import 'package:flutter/material.dart';
import 'package:frlutter_demo_mixpanel/services/mixpanel_service.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final mixPanelService = MixPanelService();
final String userName = 'Francisco';
final String userId = '123';
final String email = 'fnoceda83@gmail.com';
final String country = 'PY';
final String city = 'Asunción';
//IMPORTANT: the identifier for the user inside the mixpanel dashboard
final String userIdentity = 'fnoceda83';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ElevatedButton(
onPressed: () {
mixPanelService.signUpEvent(
userName: userName,
email: email,
country: country,
city: city,
);
// better call this function when you have approved your sign up
mixPanelService.changeIdentify(
newUserIdentity: userIdentity,
userId: userId,
userName: userName,
email: email,
country: country,
city: city,
);
},
child: const Text('Sign up event'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
mixPanelService.signInEvent(
userName: userName,
);
// better call this function when you have approved your sign in
mixPanelService.changeIdentify(
newUserIdentity: userIdentity,
userId: userId,
userName: userName,
email: email,
country: country,
city: city,
);
},
child: const Text('Sign in event'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
mixPanelService.showHomePageEvent(userName: userName);
},
child: const Text('Home screen'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
mixPanelService.visitProductEvent(
userName: userName,
produtId: '1',
);
},
child: const Text('Visit product 1 event'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
mixPanelService.visitProductEvent(
userName: userName,
produtId: '2',
);
},
child: const Text('Visit product 2 event'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
mixPanelService.buyProductEvent(
userName: userName,
produtId: '2',
);
},
child: const Text('Buy product 2 event'),
),
],
),
),
),
);
}
}
Step 6
Check your events on mix-panel
Logged on mix-panel navigate to the [Events] option
In the next tutorial, we will see how to integrate with GoRouter to track when a user opens a new screen or navigates back, using a simple function for all routes and avoiding many functions!
Demo project on github
https://github.com/fnoceda/flutter_mixpanel_demo
Enjoy it!
Screens


