@@ -8,8 +8,10 @@ import 'package:mixpanel_flutter/codec/mixpanel_message_codec.dart';
8
8
9
9
/// The primary class for integrating Mixpanel with your app.
10
10
class Mixpanel {
11
- static const MethodChannel _channel = const MethodChannel (
12
- 'mixpanel_flutter' , StandardMethodCodec (MixpanelMessageCodec ()));
11
+ static final MethodChannel _channel = kIsWeb
12
+ ? const MethodChannel ('mixpanel_flutter' )
13
+ : const MethodChannel (
14
+ 'mixpanel_flutter' , StandardMethodCodec (MixpanelMessageCodec ()));
13
15
static Map <String , String > _mixpanelProperties = {
14
16
'\$ lib_version' : '2.4.3' ,
15
17
'mp_lib' : 'flutter' ,
@@ -42,8 +44,8 @@ class Mixpanel {
42
44
allProperties['optOutTrackingDefault' ] = optOutTrackingDefault;
43
45
allProperties['trackAutomaticEvents' ] = trackAutomaticEvents;
44
46
allProperties['mixpanelProperties' ] = _mixpanelProperties;
45
- allProperties['superProperties' ] = superProperties;
46
- allProperties['config' ] = config;
47
+ allProperties['superProperties' ] = _MixpanelHelper . ensureSerializableProperties ( superProperties) ;
48
+ allProperties['config' ] = _MixpanelHelper . ensureSerializableProperties ( config) ;
47
49
await _channel.invokeMethod <void >('initialize' , allProperties);
48
50
return Mixpanel (token);
49
51
}
@@ -196,7 +198,7 @@ class Mixpanel {
196
198
}) async {
197
199
if (_MixpanelHelper .isValidString (eventName)) {
198
200
await _channel.invokeMethod <void >('track' ,
199
- < String , dynamic > {'eventName' : eventName, 'properties' : properties});
201
+ < String , dynamic > {'eventName' : eventName, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
200
202
} else {
201
203
developer.log ('`track` failed: eventName cannot be blank' ,
202
204
name: 'Mixpanel' );
@@ -229,8 +231,8 @@ class Mixpanel {
229
231
if (_MixpanelHelper .isValidString (eventName)) {
230
232
await _channel.invokeMethod <void >('trackWithGroups' , < String , dynamic > {
231
233
'eventName' : eventName,
232
- 'properties' : properties,
233
- 'groups' : groups
234
+ 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) ,
235
+ 'groups' : _MixpanelHelper . ensureSerializableProperties ( groups)
234
236
});
235
237
} else {
236
238
developer.log ('`trackWithGroups` failed: eventName cannot be blank' ,
@@ -245,7 +247,7 @@ class Mixpanel {
245
247
void setGroup (String groupKey, dynamic groupID) {
246
248
if (_MixpanelHelper .isValidString (groupKey)) {
247
249
_channel.invokeMethod <void >('setGroup' ,
248
- < String , dynamic > {'groupKey' : groupKey, 'groupID' : groupID});
250
+ < String , dynamic > {'groupKey' : groupKey, 'groupID' : _MixpanelHelper . ensureSerializableValue ( groupID) });
249
251
} else {
250
252
developer.log ('`setGroup` failed: groupKey cannot be blank' ,
251
253
name: 'Mixpanel' );
@@ -260,7 +262,7 @@ class Mixpanel {
260
262
/// return an instance of MixpanelGroup that you can use to update
261
263
/// records in Mixpanel Group Analytics
262
264
MixpanelGroup getGroup (String groupKey, dynamic groupID) {
263
- return new MixpanelGroup (this ._token, groupKey, groupID);
265
+ return new MixpanelGroup (this ._token, groupKey, _MixpanelHelper . ensureSerializableValue ( groupID) );
264
266
}
265
267
266
268
/// Add a group to this user's membership for a particular group key
@@ -270,7 +272,7 @@ class Mixpanel {
270
272
void addGroup (String groupKey, dynamic groupID) {
271
273
if (_MixpanelHelper .isValidString (groupKey)) {
272
274
_channel.invokeMethod <void >('addGroup' ,
273
- < String , dynamic > {'groupKey' : groupKey, 'groupID' : groupID});
275
+ < String , dynamic > {'groupKey' : groupKey, 'groupID' : _MixpanelHelper . ensureSerializableValue ( groupID) });
274
276
} else {
275
277
developer.log ('`addGroup` failed: groupKey cannot be blank' ,
276
278
name: 'Mixpanel' );
@@ -284,7 +286,7 @@ class Mixpanel {
284
286
void removeGroup (String groupKey, dynamic groupID) {
285
287
if (_MixpanelHelper .isValidString (groupKey)) {
286
288
_channel.invokeMethod <void >('removeGroup' ,
287
- < String , dynamic > {'groupKey' : groupKey, 'groupID' : groupID});
289
+ < String , dynamic > {'groupKey' : groupKey, 'groupID' : _MixpanelHelper . ensureSerializableValue ( groupID) });
288
290
} else {
289
291
developer.log ('`removeGroup` failed: groupKey cannot be blank' ,
290
292
name: 'Mixpanel' );
@@ -301,7 +303,7 @@ class Mixpanel {
301
303
void deleteGroup (String groupKey, dynamic groupID) {
302
304
if (_MixpanelHelper .isValidString (groupKey)) {
303
305
_channel.invokeMethod <void >('deleteGroup' ,
304
- < String , dynamic > {'groupKey' : groupKey, 'groupID' : groupID});
306
+ < String , dynamic > {'groupKey' : groupKey, 'groupID' : _MixpanelHelper . ensureSerializableValue ( groupID) });
305
307
} else {
306
308
developer.log ('`deleteGroup` failed: groupKey cannot be blank' ,
307
309
name: 'Mixpanel' );
@@ -323,7 +325,7 @@ class Mixpanel {
323
325
/// * [properties] A Map containing super properties to register
324
326
Future <void > registerSuperProperties (Map <String , dynamic > properties) async {
325
327
await _channel.invokeMethod <void >(
326
- 'registerSuperProperties' , < String , dynamic > {'properties' : properties});
328
+ 'registerSuperProperties' , < String , dynamic > {'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
327
329
}
328
330
329
331
/// Register super properties for events, only if no other super property with the
@@ -336,7 +338,7 @@ class Mixpanel {
336
338
Map <String , dynamic > properties,
337
339
) async {
338
340
await _channel.invokeMethod <void >('registerSuperPropertiesOnce' ,
339
- < String , dynamic > {'properties' : properties});
341
+ < String , dynamic > {'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
340
342
}
341
343
342
344
/// Remove a single superProperty, so that it will not be sent with future calls to track().
@@ -450,7 +452,10 @@ class Mixpanel {
450
452
/// persist across stops and starts of your application, until you make another
451
453
/// call to identify using a different id.
452
454
class People {
453
- static const MethodChannel _channel = const MethodChannel ('mixpanel_flutter' );
455
+ static final MethodChannel _channel = kIsWeb
456
+ ? const MethodChannel ('mixpanel_flutter' )
457
+ : const MethodChannel (
458
+ 'mixpanel_flutter' , StandardMethodCodec (MixpanelMessageCodec ()));
454
459
455
460
final String _token;
456
461
@@ -467,7 +472,7 @@ class People {
467
472
if (_MixpanelHelper .isValidString (prop)) {
468
473
Map <String , dynamic > properties = {prop: to};
469
474
_channel.invokeMethod <void >('set' ,
470
- < String , dynamic > {'token' : this ._token, 'properties' : properties});
475
+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
471
476
} else {
472
477
developer.log ('`people set` failed: prop cannot be blank' ,
473
478
name: 'Mixpanel' );
@@ -482,7 +487,7 @@ class People {
482
487
if (_MixpanelHelper .isValidString (prop)) {
483
488
Map <String , dynamic > properties = {prop: to};
484
489
_channel.invokeMethod <void >('setOnce' ,
485
- < String , dynamic > {'token' : this ._token, 'properties' : properties});
490
+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
486
491
} else {
487
492
developer.log ('`people setOnce` failed: prop cannot be blank' ,
488
493
name: 'Mixpanel' );
@@ -499,7 +504,7 @@ class People {
499
504
Map <String , dynamic > properties = {prop: by};
500
505
if (_MixpanelHelper .isValidString (prop)) {
501
506
_channel.invokeMethod <void >('increment' ,
502
- < String , dynamic > {'token' : this ._token, 'properties' : properties});
507
+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
503
508
} else {
504
509
developer.log ('`people increment` failed: prop cannot be blank' ,
505
510
name: 'Mixpanel' );
@@ -516,12 +521,12 @@ class People {
516
521
if (kIsWeb || Platform .isIOS) {
517
522
Map <String , dynamic > properties = {name: value};
518
523
_channel.invokeMethod <void >('append' ,
519
- < String , dynamic > {'token' : this ._token, 'properties' : properties});
524
+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
520
525
} else {
521
526
_channel.invokeMethod <void >('append' , < String , dynamic > {
522
527
'token' : this ._token,
523
528
'name' : name,
524
- 'value' : value
529
+ 'value' : _MixpanelHelper . ensureSerializableValue ( value)
525
530
});
526
531
}
527
532
} else {
@@ -541,12 +546,12 @@ class People {
541
546
if (kIsWeb || Platform .isIOS) {
542
547
Map <String , dynamic > properties = {name: value};
543
548
_channel.invokeMethod <void >('union' ,
544
- < String , dynamic > {'token' : this ._token, 'properties' : properties});
549
+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
545
550
} else {
546
551
_channel.invokeMethod <void >('union' , < String , dynamic > {
547
552
'token' : this ._token,
548
553
'name' : name,
549
- 'value' : value
554
+ 'value' : _MixpanelHelper . ensureSerializableValue ( value)
550
555
});
551
556
}
552
557
} else {
@@ -566,12 +571,12 @@ class People {
566
571
if (kIsWeb || Platform .isIOS) {
567
572
Map <String , dynamic > properties = {name: value};
568
573
_channel.invokeMethod <void >('remove' ,
569
- < String , dynamic > {'token' : this ._token, 'properties' : properties});
574
+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
570
575
} else {
571
576
_channel.invokeMethod <void >('remove' , < String , dynamic > {
572
577
'token' : this ._token,
573
578
'name' : name,
574
- 'value' : value
579
+ 'value' : _MixpanelHelper . ensureSerializableValue ( value)
575
580
});
576
581
}
577
582
} else {
@@ -603,7 +608,7 @@ class People {
603
608
_channel.invokeMethod <void >('trackCharge' , < String , dynamic > {
604
609
'token' : this ._token,
605
610
'amount' : amount,
606
- 'properties' : properties
611
+ 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties)
607
612
});
608
613
} else {
609
614
developer.log ('`people trackCharge` failed: amount cannot be blank' ,
@@ -631,7 +636,10 @@ class People {
631
636
///
632
637
/// The MixpanelGroup object is used to update properties in a group's Group Analytics record.
633
638
class MixpanelGroup {
634
- static const MethodChannel _channel = const MethodChannel ('mixpanel_flutter' );
639
+ static final MethodChannel _channel = kIsWeb
640
+ ? const MethodChannel ('mixpanel_flutter' )
641
+ : const MethodChannel (
642
+ 'mixpanel_flutter' , StandardMethodCodec (MixpanelMessageCodec ()));
635
643
636
644
final String _token;
637
645
final String _groupKey;
@@ -656,7 +664,7 @@ class MixpanelGroup {
656
664
'token' : this ._token,
657
665
'groupKey' : this ._groupKey,
658
666
'groupID' : this ._groupID,
659
- 'properties' : properties
667
+ 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties)
660
668
});
661
669
} else {
662
670
developer.log ('`group set` failed: prop cannot be blank' ,
@@ -676,7 +684,7 @@ class MixpanelGroup {
676
684
'token' : this ._token,
677
685
'groupKey' : this ._groupKey,
678
686
'groupID' : this ._groupID,
679
- 'properties' : properties
687
+ 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties)
680
688
});
681
689
} else {
682
690
developer.log ('`group setOnce` failed: prop cannot be blank' ,
@@ -714,7 +722,7 @@ class MixpanelGroup {
714
722
'groupKey' : this ._groupKey,
715
723
'groupID' : this ._groupID,
716
724
'name' : name,
717
- 'value' : value
725
+ 'value' : _MixpanelHelper . ensureSerializableValue ( value)
718
726
});
719
727
} else {
720
728
developer.log ('`group remove` failed: name cannot be blank' ,
@@ -745,7 +753,7 @@ class MixpanelGroup {
745
753
'groupKey' : this ._groupKey,
746
754
'groupID' : this ._groupID,
747
755
'name' : name,
748
- 'value' : value
756
+ 'value' : _MixpanelHelper . ensureSerializableValue ( value)
749
757
});
750
758
}
751
759
}
@@ -755,4 +763,32 @@ class _MixpanelHelper {
755
763
// ignore: unnecessary_null_comparison
756
764
return input != null && input.isNotEmpty;
757
765
}
766
+
767
+ /// Converts complex types to basic types for web platform
768
+ static dynamic ensureSerializableValue (dynamic value) {
769
+ if (! kIsWeb) {
770
+ return value;
771
+ }
772
+ if (value == null ) {
773
+ return null ;
774
+ } else if (value is DateTime ) {
775
+ return value.toIso8601String ();
776
+ } else if (value is Uri ) {
777
+ return value.toString ();
778
+ } else if (value is Map ) {
779
+ return value.map ((k, v) => MapEntry (k, ensureSerializableValue (v)));
780
+ } else if (value is List ) {
781
+ return value.map ((v) => ensureSerializableValue (v)).toList ();
782
+ } else {
783
+ return value;
784
+ }
785
+ }
786
+
787
+ /// Converts properties map for web platform
788
+ static Map <String , dynamic >? ensureSerializableProperties (Map <String , dynamic >? properties) {
789
+ if (! kIsWeb || properties == null ) {
790
+ return properties;
791
+ }
792
+ return properties.map ((k, v) => MapEntry (k, ensureSerializableValue (v)));
793
+ }
758
794
}
0 commit comments