From d290366e0dfed81d4f534f52bba0b92e6ff31c46 Mon Sep 17 00:00:00 2001 From: Oscar Bazaldua <511911+oscb@users.noreply.github.com> Date: Fri, 26 May 2023 13:24:27 -0700 Subject: [PATCH] fix: Firebase plugin fixes - Refactor the object mappings to properly do item recursive mappings - Refactor the Firebase log calls to do some validation previously missing - Refactor the item mapping as it wasn't previously setting any properties. - Removes the `json_annotation` dependency from Firebase plugin - Sanitize event name - Adds default `logEvent` for any event name not in a standard case for Firebase - Removed `metrics` from the `RawEvent` class - Removes several files that should be ignored in the repo (WIP) --- .gitignore | 4 +- packages/core/lib/event.dart | 1 - packages/core/lib/event.g.dart | 26 +- packages/core/lib/map_transform.dart | 94 +-- packages/core/lib/plugin.dart | 24 +- packages/core/pubspec.lock | 674 ------------------ packages/core/test/mocks/mocks.mocks.dart | 217 ++---- .../plugins/plugin_firebase/.flutter-plugins | 12 - .../.flutter-plugins-dependencies | 1 - .../plugin_firebase/lib/plugin_firebase.dart | 160 +++-- .../plugin_firebase/lib/properties.dart | 59 +- .../plugin_firebase/lib/properties.g.dart | 15 - packages/plugins/plugin_firebase/pubspec.yaml | 1 - 13 files changed, 257 insertions(+), 1031 deletions(-) delete mode 100644 packages/core/pubspec.lock delete mode 100644 packages/plugins/plugin_firebase/.flutter-plugins delete mode 100644 packages/plugins/plugin_firebase/.flutter-plugins-dependencies delete mode 100644 packages/plugins/plugin_firebase/lib/properties.g.dart diff --git a/.gitignore b/.gitignore index 96486fd..4ff52c9 100644 --- a/.gitignore +++ b/.gitignore @@ -23,8 +23,10 @@ migrate_working_dir/ # Flutter/Dart/Pub related # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. -/pubspec.lock +pubspec.lock **/doc/api/ .dart_tool/ .packages build/ +.flutter-plugins +.flutter-plugins-dependencies diff --git a/packages/core/lib/event.dart b/packages/core/lib/event.dart index 4348f0d..a675b9a 100644 --- a/packages/core/lib/event.dart +++ b/packages/core/lib/event.dart @@ -51,7 +51,6 @@ abstract class RawEvent with JSONSerialisable { Context? context; Map? integrations; - List>? metrics; @JsonKey(name: "_metadata") DestinationMetadata? metadata; diff --git a/packages/core/lib/event.g.dart b/packages/core/lib/event.g.dart index 5343885..5930fba 100644 --- a/packages/core/lib/event.g.dart +++ b/packages/core/lib/event.g.dart @@ -42,9 +42,6 @@ TrackEvent _$TrackEventFromJson(Map json) => TrackEvent( ? null : Context.fromJson(json['context'] as Map) ..integrations = json['integrations'] as Map? - ..metrics = (json['metrics'] as List?) - ?.map((e) => e as Map) - .toList() ..metadata = json['_metadata'] == null ? null : DestinationMetadata.fromJson( @@ -58,7 +55,6 @@ Map _$TrackEventToJson(TrackEvent instance) => 'timestamp': instance.timestamp, 'context': instance.context?.toJson(), 'integrations': instance.integrations, - 'metrics': instance.metrics, '_metadata': instance.metadata?.toJson(), 'event': instance.event, 'properties': instance.properties, @@ -78,9 +74,6 @@ IdentifyEvent _$IdentifyEventFromJson(Map json) => ? null : Context.fromJson(json['context'] as Map) ..integrations = json['integrations'] as Map? - ..metrics = (json['metrics'] as List?) - ?.map((e) => e as Map) - .toList() ..metadata = json['_metadata'] == null ? null : DestinationMetadata.fromJson( @@ -94,7 +87,6 @@ Map _$IdentifyEventToJson(IdentifyEvent instance) => 'timestamp': instance.timestamp, 'context': instance.context?.toJson(), 'integrations': instance.integrations, - 'metrics': instance.metrics, '_metadata': instance.metadata?.toJson(), 'traits': instance.traits?.toJson(), }; @@ -113,9 +105,6 @@ GroupEvent _$GroupEventFromJson(Map json) => GroupEvent( ? null : Context.fromJson(json['context'] as Map) ..integrations = json['integrations'] as Map? - ..metrics = (json['metrics'] as List?) - ?.map((e) => e as Map) - .toList() ..metadata = json['_metadata'] == null ? null : DestinationMetadata.fromJson( @@ -129,7 +118,6 @@ Map _$GroupEventToJson(GroupEvent instance) => 'timestamp': instance.timestamp, 'context': instance.context?.toJson(), 'integrations': instance.integrations, - 'metrics': instance.metrics, '_metadata': instance.metadata?.toJson(), 'groupId': instance.groupId, 'traits': instance.traits?.toJson(), @@ -146,9 +134,6 @@ AliasEvent _$AliasEventFromJson(Map json) => AliasEvent( ? null : Context.fromJson(json['context'] as Map) ..integrations = json['integrations'] as Map? - ..metrics = (json['metrics'] as List?) - ?.map((e) => e as Map) - .toList() ..metadata = json['_metadata'] == null ? null : DestinationMetadata.fromJson( @@ -162,7 +147,6 @@ Map _$AliasEventToJson(AliasEvent instance) => 'timestamp': instance.timestamp, 'context': instance.context?.toJson(), 'integrations': instance.integrations, - 'metrics': instance.metrics, '_metadata': instance.metadata?.toJson(), 'previousId': instance.previousId, }; @@ -179,9 +163,6 @@ ScreenEvent _$ScreenEventFromJson(Map json) => ScreenEvent( ? null : Context.fromJson(json['context'] as Map) ..integrations = json['integrations'] as Map? - ..metrics = (json['metrics'] as List?) - ?.map((e) => e as Map) - .toList() ..metadata = json['_metadata'] == null ? null : DestinationMetadata.fromJson( @@ -195,7 +176,6 @@ Map _$ScreenEventToJson(ScreenEvent instance) => 'timestamp': instance.timestamp, 'context': instance.context?.toJson(), 'integrations': instance.integrations, - 'metrics': instance.metrics, '_metadata': instance.metadata?.toJson(), 'name': instance.name, 'properties': instance.properties, @@ -272,10 +252,12 @@ GroupTraits _$GroupTraitsFromJson(Map json) => GroupTraits( phone: json['phone'] as String?, plan: json['plan'] as String?, website: json['website'] as String?, - ); + )..custom = json['custom'] as Map; Map _$GroupTraitsToJson(GroupTraits instance) { - final val = {}; + final val = { + 'custom': instance.custom, + }; void writeNotNull(String key, dynamic value) { if (value != null) { diff --git a/packages/core/lib/map_transform.dart b/packages/core/lib/map_transform.dart index 065d35d..8aa407a 100644 --- a/packages/core/lib/map_transform.dart +++ b/packages/core/lib/map_transform.dart @@ -1,82 +1,44 @@ -// class PropertyMap { -// final Set? keys; -// final bool optional; - -// PropertyMap({this.keys, this.optional = false}); -// } - class PropertyMapper { - final Set sourceKeys; + final String targetKey; final dynamic Function(dynamic)? fromJson; - const PropertyMapper(this.sourceKeys, {this.fromJson}); + const PropertyMapper(this.targetKey, {this.fromJson}); } -dynamic recurseMapper( - dynamic value, Map propertiesMapper) { +dynamic recurseMapper(dynamic value, Map mappings) { if (value is List) { - return value.map((value) => recurseMapper(value, propertiesMapper)); + return value.map((value) => recurseMapper(value, mappings)); + } else if (value is Map) { + return mapProperties(value, mappings); } else if (value is Map) { - value.map( - (key, value) => MapEntry(key, recurseMapper(value, propertiesMapper))); + return value + .map((key, value) => MapEntry(key, recurseMapper(value, mappings))); } else { return value; } } -dynamic Function(String targetKey, - {bool? optional, dynamic Function(dynamic)? fromJson}) - propertyMapper(Map? properties, - Map propertiesMapper) { - return (String targetKey, - {bool? optional, dynamic Function(dynamic)? fromJson}) { - final propertyMapper = propertiesMapper[targetKey]; - if (properties != null) { - for (final sourceKey in (propertyMapper != null - ? propertyMapper.sourceKeys - : {targetKey})) { - final value = properties[sourceKey]; - if (value != null) { - return fromJson == null - ? (propertyMapper?.fromJson == null - ? value - : propertyMapper?.fromJson!(value)) - : fromJson(value); - } - } - } - if (optional == null || optional == false) { - throw Exception( - "Missing properties: ${propertyMapper == null ? targetKey : propertyMapper.sourceKeys.join(',')}"); - } else { - return null; - } - }; -} +Map mapProperties( + Map? properties, Map mappings) { + final Map output = {}; -// Map mapProperties( -// Map properties, Map mapper) { -// final Map output = {}; -// final Set missing = {}; + if (properties == null) { + return {}; + } -// for (final entry in mapper.entries) { -// var found = false; -// for (final sourceKey in entry.value.keys ?? {entry.key}) { -// final value = properties[sourceKey]; -// if (value != null) { -// output[entry.key] = value; -// found = true; -// break; -// } -// } -// if (!found && !entry.value.optional) { -// missing.add(entry.value.keys?.first ?? entry.key); -// } -// } + for (final entry in properties.entries) { + final sourceKey = entry.key; + final sourceValue = properties[sourceKey]; + if (mappings.containsKey(sourceKey)) { + final mapping = mappings[sourceKey]!; -// if (missing.isNotEmpty) { -// throw Exception("Missing properties: ${missing.join(',')}"); -// } + output[mapping.targetKey] = (mapping.fromJson != null) + ? mapping.fromJson!(sourceValue) + : sourceValue; + } else { + output[sourceKey] = sourceValue; + } + } -// return output; -// } + return output; +} diff --git a/packages/core/lib/plugin.dart b/packages/core/lib/plugin.dart index 6b0085f..53408b0 100644 --- a/packages/core/lib/plugin.dart +++ b/packages/core/lib/plugin.dart @@ -144,13 +144,31 @@ abstract class DestinationPlugin extends EventPlugin { timeline.remove(plugin); } - @override - Future execute(RawEvent event) async { + Future process(RawEvent event) async { if (!_isEnabled(event)) { return null; } - return timeline.process(event); + final beforeResult = await timeline.applyPlugins(PluginType.before, event); + if (beforeResult == null) { + return null; + } + + final enrichmentResult = + await timeline.applyPlugins(PluginType.enrichment, event); + if (enrichmentResult == null) { + return null; + } + + await super.execute(enrichmentResult); + + final afterResult = await timeline.applyPlugins(PluginType.after, event); + return afterResult; + } + + @override + Future execute(RawEvent event) async { + return process(event); } } diff --git a/packages/core/pubspec.lock b/packages/core/pubspec.lock deleted file mode 100644 index fe137ff..0000000 --- a/packages/core/pubspec.lock +++ /dev/null @@ -1,674 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - sha256: "0c80aeab9bc807ab10022cd3b2f4cf2ecdf231949dc1ddd9442406a003f19201" - url: "https://pub.dev" - source: hosted - version: "52.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - sha256: cd8ee83568a77f3ae6b913a36093a1c9b1264e7cb7f834d9ddd2311dade9c1f4 - url: "https://pub.dev" - source: hosted - version: "5.4.0" - args: - dependency: transitive - description: - name: args - sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611" - url: "https://pub.dev" - source: hosted - version: "2.3.2" - async: - dependency: transitive - description: - name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 - url: "https://pub.dev" - source: hosted - version: "2.10.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - build: - dependency: transitive - description: - name: build - sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" - url: "https://pub.dev" - source: hosted - version: "2.3.1" - build_config: - dependency: transitive - description: - name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 - url: "https://pub.dev" - source: hosted - version: "1.1.1" - build_daemon: - dependency: transitive - description: - name: build_daemon - sha256: "6bc5544ea6ce4428266e7ea680e945c68806c4aae2da0eb5e9ccf38df8d6acbf" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - build_resolvers: - dependency: transitive - description: - name: build_resolvers - sha256: "7c35a3a7868626257d8aee47b51c26b9dba11eaddf3431117ed2744951416aab" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - build_runner: - dependency: "direct dev" - description: - name: build_runner - sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727 - url: "https://pub.dev" - source: hosted - version: "2.3.3" - build_runner_core: - dependency: transitive - description: - name: build_runner_core - sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292" - url: "https://pub.dev" - source: hosted - version: "7.2.7" - built_collection: - dependency: transitive - description: - name: built_collection - sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" - url: "https://pub.dev" - source: hosted - version: "5.1.1" - built_value: - dependency: transitive - description: - name: built_value - sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725" - url: "https://pub.dev" - source: hosted - version: "8.4.3" - characters: - dependency: transitive - description: - name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c - url: "https://pub.dev" - source: hosted - version: "1.2.1" - checked_yaml: - dependency: transitive - description: - name: checked_yaml - sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - code_builder: - dependency: transitive - description: - name: code_builder - sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe" - url: "https://pub.dev" - source: hosted - version: "4.4.0" - collection: - dependency: transitive - description: - name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 - url: "https://pub.dev" - source: hosted - version: "1.17.0" - convert: - dependency: transitive - description: - name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" - url: "https://pub.dev" - source: hosted - version: "3.1.1" - crypto: - dependency: transitive - description: - name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 - url: "https://pub.dev" - source: hosted - version: "3.0.2" - dart_style: - dependency: transitive - description: - name: dart_style - sha256: "7a03456c3490394c8e7665890333e91ae8a49be43542b616e414449ac358acd4" - url: "https://pub.dev" - source: hosted - version: "2.2.4" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - ffi: - dependency: transitive - description: - name: ffi - sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 - url: "https://pub.dev" - source: hosted - version: "2.0.1" - file: - dependency: transitive - description: - name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" - url: "https://pub.dev" - source: hosted - version: "6.1.4" - fixnum: - dependency: transitive - description: - name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_fgbg: - dependency: "direct main" - description: - name: flutter_fgbg - sha256: d37511eef6afb7e2e3f2278ec6498bb12c650ed517c81bcd09452d910e8b9174 - url: "https://pub.dev" - source: hosted - version: "0.2.2" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c - url: "https://pub.dev" - source: hosted - version: "2.0.1" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - frontend_server_client: - dependency: transitive - description: - name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" - url: "https://pub.dev" - source: hosted - version: "3.2.0" - glob: - dependency: transitive - description: - name: glob - sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - graphs: - dependency: transitive - description: - name: graphs - sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2 - url: "https://pub.dev" - source: hosted - version: "2.2.0" - http: - dependency: "direct main" - description: - name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" - url: "https://pub.dev" - source: hosted - version: "0.13.5" - http_multi_server: - dependency: transitive - description: - name: http_multi_server - sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - io: - dependency: transitive - description: - name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" - url: "https://pub.dev" - source: hosted - version: "1.0.4" - js: - dependency: transitive - description: - name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" - url: "https://pub.dev" - source: hosted - version: "0.6.5" - json_annotation: - dependency: "direct main" - description: - name: json_annotation - sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317 - url: "https://pub.dev" - source: hosted - version: "4.8.0" - json_serializable: - dependency: "direct dev" - description: - name: json_serializable - sha256: dadc08bd61f72559f938dd08ec20dbfec6c709bba83515085ea943d2078d187a - url: "https://pub.dev" - source: hosted - version: "6.6.1" - lints: - dependency: transitive - description: - name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - logger: - dependency: "direct main" - description: - name: logger - sha256: "5076f09225f91dc49289a4ccb92df2eeea9ea01cf7c26d49b3a1f04c6a49eec1" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - logging: - dependency: transitive - description: - name: logging - sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - matcher: - dependency: transitive - description: - name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" - url: "https://pub.dev" - source: hosted - version: "0.12.13" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 - url: "https://pub.dev" - source: hosted - version: "0.2.0" - meta: - dependency: transitive - description: - name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" - url: "https://pub.dev" - source: hosted - version: "1.8.0" - mime: - dependency: transitive - description: - name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e - url: "https://pub.dev" - source: hosted - version: "1.0.4" - mockito: - dependency: "direct dev" - description: - name: mockito - sha256: "2a8a17b82b1bde04d514e75d90d634a0ac23f6cb4991f6098009dd56836aeafe" - url: "https://pub.dev" - source: hosted - version: "5.3.2" - package_config: - dependency: transitive - description: - name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - path: - dependency: transitive - description: - name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b - url: "https://pub.dev" - source: hosted - version: "1.8.2" - path_provider: - dependency: "direct main" - description: - name: path_provider - sha256: "04890b994ee89bfa80bf3080bfec40d5a92c5c7a785ebb02c13084a099d2b6f9" - url: "https://pub.dev" - source: hosted - version: "2.0.13" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - sha256: "7623b7d4be0f0f7d9a8b5ee6879fc13e4522d4c875ab86801dee4af32b54b83e" - url: "https://pub.dev" - source: hosted - version: "2.0.23" - path_provider_foundation: - dependency: transitive - description: - name: path_provider_foundation - sha256: eec003594f19fe2456ea965ae36b3fc967bc5005f508890aafe31fa75e41d972 - url: "https://pub.dev" - source: hosted - version: "2.1.2" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - sha256: "525ad5e07622d19447ad740b1ed5070031f7a5437f44355ae915ff56e986429a" - url: "https://pub.dev" - source: hosted - version: "2.1.9" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" - url: "https://pub.dev" - source: hosted - version: "2.0.6" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - sha256: "642ddf65fde5404f83267e8459ddb4556316d3ee6d511ed193357e25caa3632d" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - pigeon: - dependency: "direct dev" - description: - name: pigeon - sha256: b9b8877c7e238ccc6c27bed204e326eaf00bf7aa3c2f1b622457116eaa831821 - url: "https://pub.dev" - source: hosted - version: "7.2.1" - platform: - dependency: transitive - description: - name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: "direct main" - description: - name: plugin_platform_interface - sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a - url: "https://pub.dev" - source: hosted - version: "2.1.3" - pool: - dependency: transitive - description: - name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" - url: "https://pub.dev" - source: hosted - version: "1.5.1" - process: - dependency: transitive - description: - name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" - url: "https://pub.dev" - source: hosted - version: "4.2.4" - pub_semver: - dependency: transitive - description: - name: pub_semver - sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" - url: "https://pub.dev" - source: hosted - version: "2.1.3" - pubspec_parse: - dependency: transitive - description: - name: pubspec_parse - sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a" - url: "https://pub.dev" - source: hosted - version: "1.2.1" - shelf: - dependency: transitive - description: - name: shelf - sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c - url: "https://pub.dev" - source: hosted - version: "1.4.0" - shelf_web_socket: - dependency: transitive - description: - name: shelf_web_socket - sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 - url: "https://pub.dev" - source: hosted - version: "1.0.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_gen: - dependency: transitive - description: - name: source_gen - sha256: c2bea18c95cfa0276a366270afaa2850b09b4a76db95d546f3d003dcc7011298 - url: "https://pub.dev" - source: hosted - version: "1.2.7" - source_helper: - dependency: transitive - description: - name: source_helper - sha256: "3b67aade1d52416149c633ba1bb36df44d97c6b51830c2198e934e3fca87ca1f" - url: "https://pub.dev" - source: hosted - version: "1.3.3" - source_span: - dependency: transitive - description: - name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 - url: "https://pub.dev" - source: hosted - version: "1.9.1" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - state_notifier: - dependency: "direct main" - description: - name: state_notifier - sha256: "8fe42610f179b843b12371e40db58c9444f8757f8b69d181c97e50787caed289" - url: "https://pub.dev" - source: hosted - version: "0.7.2+1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - stream_transform: - dependency: transitive - description: - name: stream_transform - sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 - url: "https://pub.dev" - source: hosted - version: "0.4.16" - timing: - dependency: transitive - description: - name: timing - sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" - url: "https://pub.dev" - source: hosted - version: "1.0.1" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - uuid: - dependency: "direct main" - description: - name: uuid - sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" - url: "https://pub.dev" - source: hosted - version: "3.0.7" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - watcher: - dependency: transitive - description: - name: watcher - sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b - url: "https://pub.dev" - source: hosted - version: "2.3.0" - win32: - dependency: transitive - description: - name: win32 - sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 - url: "https://pub.dev" - source: hosted - version: "3.1.3" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 - url: "https://pub.dev" - source: hosted - version: "1.0.0" - yaml: - dependency: transitive - description: - name: yaml - sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" - url: "https://pub.dev" - source: hosted - version: "3.1.1" -sdks: - dart: ">=2.19.2 <3.0.0" - flutter: ">=3.0.0" diff --git a/packages/core/test/mocks/mocks.mocks.dart b/packages/core/test/mocks/mocks.mocks.dart index 8113897..175a9ef 100644 --- a/packages/core/test/mocks/mocks.mocks.dart +++ b/packages/core/test/mocks/mocks.mocks.dart @@ -1,18 +1,17 @@ -// Mocks generated by Mockito 5.3.2 from annotations -// in analytics/example/windows/flutter/ephemeral/.plugin_symlinks/analytics/example/linux/flutter/ephemeral/.plugin_symlinks/analytics/example/ios/.symlinks/plugins/analytics/example/macos/Flutter/ephemeral/.symlinks/plugins/analytics/test/mocks/mocks.dart. +// Mocks generated by Mockito 5.4.0 from annotations +// in analytics/test/mocks/mocks.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i7; +import 'dart:async' as _i5; import 'dart:convert' as _i2; -import 'dart:typed_data' as _i6; +import 'dart:typed_data' as _i7; -import 'package:analytics/analytics.dart' as _i9; -import 'package:analytics/event.dart' as _i10; -import 'package:analytics/logger.dart' as _i5; -import 'package:analytics/state.dart' as _i11; +import 'package:analytics/event.dart' as _i9; +import 'package:analytics/logger.dart' as _i6; +import 'package:analytics/state.dart' as _i10; import 'package:analytics/utils/http_client.dart' as _i8; -import 'package:analytics/utils/store/store.dart' as _i12; +import 'package:analytics/utils/store/store.dart' as _i11; import 'package:http/http.dart' as _i4; import 'package:http/src/byte_stream.dart' as _i3; import 'package:mockito/mockito.dart' as _i1; @@ -69,19 +68,8 @@ class _FakeStreamedResponse_3 extends _i1.SmartFake ); } -class _FakeWeakReference_4 extends _i1.SmartFake - implements WeakReference { - _FakeWeakReference_4( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeRequest_5 extends _i1.SmartFake implements _i4.Request { - _FakeRequest_5( +class _FakeFuture_4 extends _i1.SmartFake implements _i5.Future { + _FakeFuture_4( Object parent, Invocation parentInvocation, ) : super( @@ -93,9 +81,9 @@ class _FakeRequest_5 extends _i1.SmartFake implements _i4.Request { /// A class which mocks [LogTarget]. /// /// See the documentation for Mockito's code generation for more information. -class MockLogTarget extends _i1.Mock implements _i5.LogTarget { +class MockLogTarget extends _i1.Mock implements _i6.LogTarget { @override - void parseLog(_i5.LogMessage? log) => super.noSuchMethod( + void parseLog(_i6.LogMessage? log) => super.noSuchMethod( Invocation.method( #parseLog, [log], @@ -143,11 +131,11 @@ class MockRequest extends _i1.Mock implements _i4.Request { returnValueForMissingStub: null, ); @override - _i6.Uint8List get bodyBytes => (super.noSuchMethod( + _i7.Uint8List get bodyBytes => (super.noSuchMethod( Invocation.getter(#bodyBytes), - returnValue: _i6.Uint8List(0), - returnValueForMissingStub: _i6.Uint8List(0), - ) as _i6.Uint8List); + returnValue: _i7.Uint8List(0), + returnValueForMissingStub: _i7.Uint8List(0), + ) as _i7.Uint8List); @override set bodyBytes(List? value) => super.noSuchMethod( Invocation.setter( @@ -278,13 +266,13 @@ class MockRequest extends _i1.Mock implements _i4.Request { ), ) as _i3.ByteStream); @override - _i7.Future<_i4.StreamedResponse> send() => (super.noSuchMethod( + _i5.Future<_i4.StreamedResponse> send() => (super.noSuchMethod( Invocation.method( #send, [], ), returnValue: - _i7.Future<_i4.StreamedResponse>.value(_FakeStreamedResponse_3( + _i5.Future<_i4.StreamedResponse>.value(_FakeStreamedResponse_3( this, Invocation.method( #send, @@ -292,21 +280,21 @@ class MockRequest extends _i1.Mock implements _i4.Request { ), )), returnValueForMissingStub: - _i7.Future<_i4.StreamedResponse>.value(_FakeStreamedResponse_3( + _i5.Future<_i4.StreamedResponse>.value(_FakeStreamedResponse_3( this, Invocation.method( #send, [], ), )), - ) as _i7.Future<_i4.StreamedResponse>); + ) as _i5.Future<_i4.StreamedResponse>); } /// A class which mocks [StreamSubscription]. /// /// See the documentation for Mockito's code generation for more information. class MockStreamSubscription extends _i1.Mock - implements _i7.StreamSubscription { + implements _i5.StreamSubscription { @override bool get isPaused => (super.noSuchMethod( Invocation.getter(#isPaused), @@ -314,14 +302,14 @@ class MockStreamSubscription extends _i1.Mock returnValueForMissingStub: false, ) as bool); @override - _i7.Future cancel() => (super.noSuchMethod( + _i5.Future cancel() => (super.noSuchMethod( Invocation.method( #cancel, [], ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); @override void onData(void Function(T)? handleData) => super.noSuchMethod( Invocation.method( @@ -347,7 +335,7 @@ class MockStreamSubscription extends _i1.Mock returnValueForMissingStub: null, ); @override - void pause([_i7.Future? resumeSignal]) => super.noSuchMethod( + void pause([_i5.Future? resumeSignal]) => super.noSuchMethod( Invocation.method( #pause, [resumeSignal], @@ -363,79 +351,36 @@ class MockStreamSubscription extends _i1.Mock returnValueForMissingStub: null, ); @override - _i7.Future asFuture([E? futureValue]) => (super.noSuchMethod( + _i5.Future asFuture([E? futureValue]) => (super.noSuchMethod( Invocation.method( #asFuture, [futureValue], ), - returnValue: _i7.Future.value(null), - returnValueForMissingStub: _i7.Future.value(null), - ) as _i7.Future); -} - -/// A class which mocks [HTTPClient]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockHTTPClient extends _i1.Mock implements _i8.HTTPClient { - @override - WeakReference<_i9.Analytics> get _analytics => (super.noSuchMethod( - Invocation.getter(#analytics), - returnValue: _FakeWeakReference_4<_i9.Analytics>( - this, - Invocation.getter(#analytics), - ), - returnValueForMissingStub: _FakeWeakReference_4<_i9.Analytics>( - this, - Invocation.getter(#analytics), - ), - ) as WeakReference<_i9.Analytics>); - @override - set _analytics(WeakReference<_i9.Analytics>? _analytics) => - super.noSuchMethod( - Invocation.setter( - #analytics, - _analytics, - ), - returnValueForMissingStub: null, - ); - @override - Uri _url( - String? host, - String? path, - ) => - (super.noSuchMethod( - Invocation.method( - #segmentURL, - [ - host, - path, - ], - ), - returnValue: _FakeUri_1( + returnValue: _FakeFuture_4( this, Invocation.method( - #segmentURL, - [ - host, - path, - ], + #asFuture, + [futureValue], ), ), - returnValueForMissingStub: _FakeUri_1( + returnValueForMissingStub: _FakeFuture_4( this, Invocation.method( - #segmentURL, - [ - host, - path, - ], + #asFuture, + [futureValue], ), ), - ) as Uri); + ) as _i5.Future); +} + +/// A class which mocks [HTTPClient]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockHTTPClient extends _i1.Mock implements _i8.HTTPClient { @override - _i7.Future startBatchUpload( + _i5.Future startBatchUpload( String? writeKey, - List<_i10.RawEvent>? batch, + List<_i9.RawEvent>? batch, ) => (super.noSuchMethod( Invocation.method( @@ -445,81 +390,43 @@ class MockHTTPClient extends _i1.Mock implements _i8.HTTPClient { batch, ], ), - returnValue: _i7.Future.value(false), - returnValueForMissingStub: _i7.Future.value(false), - ) as _i7.Future); + returnValue: _i5.Future.value(false), + returnValueForMissingStub: _i5.Future.value(false), + ) as _i5.Future); @override - _i7.Future<_i11.SegmentAPISettings?> settingsFor(String? writeKey) => + _i5.Future<_i10.SegmentAPISettings?> settingsFor(String? writeKey) => (super.noSuchMethod( Invocation.method( #settingsFor, [writeKey], ), - returnValue: _i7.Future<_i11.SegmentAPISettings?>.value(), - returnValueForMissingStub: _i7.Future<_i11.SegmentAPISettings?>.value(), - ) as _i7.Future<_i11.SegmentAPISettings?>); - @override - _i4.Request _configuredRequest( - Uri? url, - String? method, { - String? body, - }) => - (super.noSuchMethod( - Invocation.method( - #configuredRequest, - [ - url, - method, - ], - {#body: body}, - ), - returnValue: _FakeRequest_5( - this, - Invocation.method( - #configuredRequest, - [ - url, - method, - ], - {#body: body}, - ), - ), - returnValueForMissingStub: _FakeRequest_5( - this, - Invocation.method( - #configuredRequest, - [ - url, - method, - ], - {#body: body}, - ), - ), - ) as _i4.Request); + returnValue: _i5.Future<_i10.SegmentAPISettings?>.value(), + returnValueForMissingStub: _i5.Future<_i10.SegmentAPISettings?>.value(), + ) as _i5.Future<_i10.SegmentAPISettings?>); } /// A class which mocks [Store]. /// /// See the documentation for Mockito's code generation for more information. -class MockStore extends _i1.Mock implements _i12.Store { +class MockStore extends _i1.Mock implements _i11.Store { @override - _i7.Future get ready => (super.noSuchMethod( + _i5.Future get ready => (super.noSuchMethod( Invocation.getter(#ready), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); @override - _i7.Future?> getPersisted(String? key) => + _i5.Future?> getPersisted(String? key) => (super.noSuchMethod( Invocation.method( #getPersisted, [key], ), - returnValue: _i7.Future?>.value(), - returnValueForMissingStub: _i7.Future?>.value(), - ) as _i7.Future?>); + returnValue: _i5.Future?>.value(), + returnValueForMissingStub: _i5.Future?>.value(), + ) as _i5.Future?>); @override - _i7.Future setPersisted( + _i5.Future setPersisted( String? key, Map? value, ) => @@ -531,9 +438,9 @@ class MockStore extends _i1.Mock implements _i12.Store { value, ], ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); @override void dispose() => super.noSuchMethod( Invocation.method( diff --git a/packages/plugins/plugin_firebase/.flutter-plugins b/packages/plugins/plugin_firebase/.flutter-plugins deleted file mode 100644 index a58f8b1..0000000 --- a/packages/plugins/plugin_firebase/.flutter-plugins +++ /dev/null @@ -1,12 +0,0 @@ -# This is a generated file; do not edit or check into version control. -analytics=/Users/charagan/code/analytics_flutter/packages/core/ -firebase_analytics=/Users/charagan/.pub-cache/hosted/pub.dev/firebase_analytics-10.1.4/ -firebase_analytics_web=/Users/charagan/.pub-cache/hosted/pub.dev/firebase_analytics_web-0.5.1+12/ -firebase_core=/Users/charagan/.pub-cache/hosted/pub.dev/firebase_core-2.7.0/ -firebase_core_web=/Users/charagan/.pub-cache/hosted/pub.dev/firebase_core_web-2.2.1/ -flutter_fgbg=/Users/charagan/.pub-cache/hosted/pub.dev/flutter_fgbg-0.2.2/ -path_provider=/Users/charagan/.pub-cache/hosted/pub.dev/path_provider-2.0.13/ -path_provider_android=/Users/charagan/.pub-cache/hosted/pub.dev/path_provider_android-2.0.23/ -path_provider_foundation=/Users/charagan/.pub-cache/hosted/pub.dev/path_provider_foundation-2.1.2/ -path_provider_linux=/Users/charagan/.pub-cache/hosted/pub.dev/path_provider_linux-2.1.9/ -path_provider_windows=/Users/charagan/.pub-cache/hosted/pub.dev/path_provider_windows-2.1.4/ diff --git a/packages/plugins/plugin_firebase/.flutter-plugins-dependencies b/packages/plugins/plugin_firebase/.flutter-plugins-dependencies deleted file mode 100644 index 778833d..0000000 --- a/packages/plugins/plugin_firebase/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"analytics","path":"/Users/charagan/code/analytics_flutter/packages/core/","native_build":true,"dependencies":["flutter_fgbg"]},{"name":"firebase_analytics","path":"/Users/charagan/.pub-cache/hosted/pub.dev/firebase_analytics-10.1.4/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/charagan/.pub-cache/hosted/pub.dev/firebase_core-2.7.0/","native_build":true,"dependencies":[]},{"name":"flutter_fgbg","path":"/Users/charagan/.pub-cache/hosted/pub.dev/flutter_fgbg-0.2.2/","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/Users/charagan/.pub-cache/hosted/pub.dev/path_provider_foundation-2.1.2/","native_build":true,"dependencies":[]}],"android":[{"name":"analytics","path":"/Users/charagan/code/analytics_flutter/packages/core/","native_build":true,"dependencies":["flutter_fgbg"]},{"name":"firebase_analytics","path":"/Users/charagan/.pub-cache/hosted/pub.dev/firebase_analytics-10.1.4/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/charagan/.pub-cache/hosted/pub.dev/firebase_core-2.7.0/","native_build":true,"dependencies":[]},{"name":"flutter_fgbg","path":"/Users/charagan/.pub-cache/hosted/pub.dev/flutter_fgbg-0.2.2/","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"/Users/charagan/.pub-cache/hosted/pub.dev/path_provider_android-2.0.23/","native_build":true,"dependencies":[]}],"macos":[{"name":"analytics","path":"/Users/charagan/code/analytics_flutter/packages/core/","native_build":true,"dependencies":[]},{"name":"firebase_analytics","path":"/Users/charagan/.pub-cache/hosted/pub.dev/firebase_analytics-10.1.4/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/charagan/.pub-cache/hosted/pub.dev/firebase_core-2.7.0/","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/Users/charagan/.pub-cache/hosted/pub.dev/path_provider_foundation-2.1.2/","native_build":true,"dependencies":[]}],"linux":[{"name":"analytics","path":"/Users/charagan/code/analytics_flutter/packages/core/","native_build":true,"dependencies":[]},{"name":"path_provider_linux","path":"/Users/charagan/.pub-cache/hosted/pub.dev/path_provider_linux-2.1.9/","native_build":false,"dependencies":[]}],"windows":[{"name":"analytics","path":"/Users/charagan/code/analytics_flutter/packages/core/","native_build":true,"dependencies":[]},{"name":"path_provider_windows","path":"/Users/charagan/.pub-cache/hosted/pub.dev/path_provider_windows-2.1.4/","native_build":false,"dependencies":[]}],"web":[{"name":"analytics","path":"/Users/charagan/code/analytics_flutter/packages/core/","dependencies":[]},{"name":"firebase_analytics_web","path":"/Users/charagan/.pub-cache/hosted/pub.dev/firebase_analytics_web-0.5.1+12/","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","path":"/Users/charagan/.pub-cache/hosted/pub.dev/firebase_core_web-2.2.1/","dependencies":[]}]},"dependencyGraph":[{"name":"analytics","dependencies":["flutter_fgbg","path_provider"]},{"name":"firebase_analytics","dependencies":["firebase_analytics_web","firebase_core"]},{"name":"firebase_analytics_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"flutter_fgbg","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2023-03-09 14:54:07.758706","version":"3.7.6"} \ No newline at end of file diff --git a/packages/plugins/plugin_firebase/lib/plugin_firebase.dart b/packages/plugins/plugin_firebase/lib/plugin_firebase.dart index 23f6b0e..50ef381 100644 --- a/packages/plugins/plugin_firebase/lib/plugin_firebase.dart +++ b/packages/plugins/plugin_firebase/lib/plugin_firebase.dart @@ -40,97 +40,101 @@ class FirebaseDestination extends DestinationPlugin { @override Future track(TrackEvent event) async { await firebaseFuture; - - final properties = propertyMapper(event.properties, propertiesMapper); + final properties = mapProperties(event.properties, mappings); try { switch (event.event) { case 'Product Clicked': + if (properties.containsKey('contentType') || + properties.containsKey('itemId')) { + throw Exception("Missing properties: contentType and itemId"); + } + await FirebaseAnalytics.instance.logSelectContent( - contentType: properties('contentType'), - itemId: properties('itemId')); + contentType: properties['contentType'].toString(), + itemId: properties['itemId'].toString()); break; case 'Product Viewed': await FirebaseAnalytics.instance.logViewItem( - currency: properties("currency", optional: true), + currency: properties["currency"]?.toString(), items: event.properties == null ? null - : [AnalyticsEventItemJson.fromJson(event.properties)], - value: properties("value", optional: true)); + : [AnalyticsEventItemJson(event.properties!)], + value: double.tryParse(properties["value"].toString())); break; case 'Product Added': await FirebaseAnalytics.instance.logAddToCart( - currency: properties("currency", optional: true), + currency: properties["currency"]?.toString(), items: event.properties == null ? null - : [AnalyticsEventItemJson.fromJson(event.properties)], - value: properties("value", optional: true)); + : [AnalyticsEventItemJson(event.properties!)], + value: double.tryParse(properties["value"].toString())); break; case 'Product Removed': await FirebaseAnalytics.instance.logRemoveFromCart( - currency: properties("currency", optional: true), + currency: properties["currency"]?.toString(), items: event.properties == null ? null - : [AnalyticsEventItemJson.fromJson(event.properties)], - value: properties("value", optional: true)); + : [AnalyticsEventItemJson(event.properties!)], + value: double.tryParse(properties["value"].toString())); break; case 'Checkout Started': await FirebaseAnalytics.instance.logBeginCheckout( - coupon: properties("coupon", optional: true), - currency: properties("currency", optional: true), - items: properties("items", optional: true), - value: properties("value", optional: true)); + coupon: properties["coupon"]?.toString(), + currency: properties["currency"]?.toString(), + items: properties["items"] as List, + value: double.tryParse(properties["value"].toString())); break; case 'Promotion Viewed': await FirebaseAnalytics.instance.logViewPromotion( - creativeName: properties("creativeName", optional: true), - creativeSlot: properties("creativeSlot", optional: true), - items: properties("items", optional: true), - locationId: properties("locationdId", optional: true), - promotionId: properties("promotionId", optional: true), - promotionName: properties("promotionName", optional: true)); + creativeName: properties["creativeName"]?.toString(), + creativeSlot: properties["creativeSlot"]?.toString(), + items: properties["items"] as List, + locationId: properties["locationdId"]?.toString(), + promotionId: properties["promotionId"]?.toString(), + promotionName: properties["promotionName"]?.toString()); break; case 'Payment Info Entered': await FirebaseAnalytics.instance.logAddPaymentInfo( - coupon: properties("coupon", optional: true), - currency: properties("currency", optional: true), - items: properties("items", optional: true), - paymentType: properties("paymentType", optional: true), - value: properties("value", optional: true)); + coupon: properties["coupon"]?.toString(), + currency: properties["currency"]?.toString(), + items: properties["items"] as List, + paymentType: properties["paymentType"]?.toString(), + value: double.tryParse(properties["value"].toString())); break; case 'Order Completed': await FirebaseAnalytics.instance.logPurchase( - affiliation: properties("affiliation", optional: true), - coupon: properties("coupon", optional: true), - currency: properties("currency", optional: true), - items: properties("items", optional: true), - shipping: properties("shipping", optional: true), - tax: properties("tax", optional: true), - transactionId: properties("transactionId", optional: true), - value: properties("value", optional: true)); + affiliation: properties["affiliation"]?.toString(), + coupon: properties["coupon"]?.toString(), + currency: properties["currency"]?.toString(), + items: properties["items"] as List, + shipping: double.tryParse(properties["shipping"].toString()), + tax: double.tryParse(properties["tax"].toString()), + transactionId: properties["transactionId"]?.toString(), + value: double.tryParse(properties["value"].toString())); break; case 'Order Refunded': await FirebaseAnalytics.instance.logRefund( - affiliation: properties("affiliation", optional: true), - coupon: properties("coupon", optional: true), - currency: properties("currency", optional: true), - items: properties("items", optional: true), - shipping: properties("shipping", optional: true), - tax: properties("tax", optional: true), - transactionId: properties("transactionId", optional: true), - value: properties("value", optional: true)); + affiliation: properties["affiliation"]?.toString(), + coupon: properties["coupon"]?.toString(), + currency: properties["currency"]?.toString(), + items: properties["items"] as List, + shipping: double.tryParse(properties["shipping"].toString()), + tax: double.tryParse(properties["tax"].toString()), + transactionId: properties["transactionId"]?.toString(), + value: double.tryParse(properties["value"].toString())); break; case 'Product List Viewed': await FirebaseAnalytics.instance.logViewItemList( - itemListId: properties("itemListId", optional: true), - itemListName: properties("itemListName", optional: true), - items: properties("items", optional: true)); + itemListId: properties["itemListId"]?.toString(), + itemListName: properties["itemListName"]?.toString(), + items: properties["items"] as List); break; case 'Product Added to Wishlist': await FirebaseAnalytics.instance.logAddToWishlist( - currency: properties("currency", optional: true), - items: properties("items", optional: true), - value: properties("value", optional: true)); + currency: properties["currency"]?.toString(), + items: properties["items"] as List, + value: double.tryParse(properties["value"].toString())); break; case 'Cart Shared': if (event.properties == null || @@ -139,35 +143,55 @@ class FirebaseDestination extends DestinationPlugin { } else if (event.properties!['products'] is List) { await Future.wait( (event.properties!['products'] as List).map((product) async { - final productProperties = - propertyMapper(product, propertiesMapper); - await FirebaseAnalytics.instance.logShare( - contentType: productProperties("contentType", optional: true), - itemId: productProperties("itemId", optional: true), - method: properties("method", optional: true)); + final productProperties = mapProperties(product, mappings); + if (productProperties.containsKey("contentType") && + productProperties.containsKey("itemId") && + productProperties.containsKey("method")) { + await FirebaseAnalytics.instance.logShare( + contentType: productProperties["contentType"].toString(), + itemId: productProperties["itemId"].toString(), + method: properties["method"].toString()); + } else { + log("Error tracking Cart Shared, product missing properties. Required: contentType, itemId, method"); + } })); } else { log("Error tracking event '${event.event}' for Firebase: products property must be a list of products"); } break; case 'Product Shared': + if (!properties.containsKey("contentType") || + !properties.containsKey("itemId") || + !properties.containsKey("method")) { + throw Exception("Missing properties: contentType, itemId, method"); + } await FirebaseAnalytics.instance.logShare( - contentType: properties("contentType", optional: true), - itemId: properties("itemId", optional: true), - method: properties("method", optional: true)); + contentType: properties["contentType"].toString(), + itemId: properties["itemId"].toString(), + method: properties["method"].toString()); break; case 'Products Searched': + if (!properties.containsKey("searchTerm")) { + throw Exception("Missing property: searchTerm"); + } + await FirebaseAnalytics.instance.logSearch( - searchTerm: properties("searchTerm"), - destination: properties("destination", optional: true), - endDate: properties("endDate", optional: true), - numberOfNights: properties("numberOfNights", optional: true), + searchTerm: properties["searchTerm"].toString(), + destination: properties["destination"]?.toString(), + endDate: properties["endDate"]?.toString(), + numberOfNights: + int.tryParse(properties["numberOfNights"].toString()), numberOfPassengers: - properties("numberOfPassengers", optional: true), - numberOfRooms: properties("numberOfRooms", optional: true), - origin: properties("origin", optional: true), - startDate: properties("startDate", optional: true), - travelClass: properties("travelClass", optional: true)); + int.tryParse(properties["numberOfPassengers"].toString()), + numberOfRooms: + int.tryParse(properties["numberOfRooms"].toString()), + origin: properties["origin"]?.toString(), + startDate: properties["startDate"]?.toString(), + travelClass: properties["travelClass"]?.toString()); + break; + default: + await FirebaseAnalytics.instance.logEvent( + name: sanitizeEventName(event.event), parameters: properties); break; } } catch (error) { diff --git a/packages/plugins/plugin_firebase/lib/properties.dart b/packages/plugins/plugin_firebase/lib/properties.dart index a93ff48..db3451c 100644 --- a/packages/plugins/plugin_firebase/lib/properties.dart +++ b/packages/plugins/plugin_firebase/lib/properties.dart @@ -1,24 +1,59 @@ import 'package:analytics/map_transform.dart'; import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:json_annotation/json_annotation.dart'; -part 'properties.g.dart'; -const Map propertiesMapper = { - "value": PropertyMapper({"total"}), - "items": PropertyMapper({"products"}, fromJson: itemsFromJson), - "itemName": PropertyMapper({"name"}), - "itemId": PropertyMapper({"product_id", "productId"}), - "searchTerm": PropertyMapper({"query"}), - "method": PropertyMapper({"share_via"}), - "contentType": PropertyMapper({"category"}) +const Map mappings = { + "total": PropertyMapper("value"), + "products": PropertyMapper("items", fromJson: itemsFromJson), + "name": PropertyMapper("itemName"), + "product_id": PropertyMapper("itemId"), + "productId": PropertyMapper("itemId"), + "query": PropertyMapper("searchTerm"), + "share_via": PropertyMapper("method"), + "category": PropertyMapper("contentType") }; dynamic itemsFromJson(dynamic items) { - return (items as List).map(AnalyticsEventItemJson.fromJson); + if (items is List) { + return items.map((item) { + final mappedObject = mapProperties(item, mappings); + return AnalyticsEventItemJson(mappedObject); + }).toList(); + } else { + return items; + } +} + +String sanitizeEventName(String eventName) { + return eventName.replaceAll(RegExp(r'[^a-zA-Z0-9]'), '_'); } @JsonSerializable() class AnalyticsEventItemJson extends AnalyticsEventItem { - static AnalyticsEventItemJson fromJson(dynamic item) => - _$AnalyticsEventItemJsonFromJson(recurseMapper(item, propertiesMapper)); + AnalyticsEventItemJson(Map json) + : super( + affiliation: json['affiliation'].toString(), + currency: json['currency'].toString(), + coupon: json['coupon'].toString(), + creativeName: json['creativeName'].toString(), + creativeSlot: json['creativeSlot'].toString(), + discount: num.tryParse(json['discount'].toString()), + index: int.tryParse(json['index'].toString()), + itemBrand: json['itemBrand'].toString(), + itemCategory: json['itemCategory'].toString(), + itemCategory2: json['itemCategory2'].toString(), + itemCategory3: json['itemCategory3'].toString(), + itemCategory4: json['itemCategory4'].toString(), + itemCategory5: json['itemCategory5'].toString(), + itemId: json['itemId'].toString(), + itemListId: json['itemListId'].toString(), + itemListName: json['itemListName'].toString(), + itemName: json['itemName'].toString(), + itemVariant: json['itemVariant'].toString(), + locationId: json['locationId'].toString(), + price: num.tryParse(json['price'].toString()), + promotionId: json['promotionId'].toString(), + promotionName: json['promotionName'].toString(), + quantity: int.tryParse(json['quantity'].toString()), + ); } diff --git a/packages/plugins/plugin_firebase/lib/properties.g.dart b/packages/plugins/plugin_firebase/lib/properties.g.dart deleted file mode 100644 index 8e5d0cb..0000000 --- a/packages/plugins/plugin_firebase/lib/properties.g.dart +++ /dev/null @@ -1,15 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'properties.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -AnalyticsEventItemJson _$AnalyticsEventItemJsonFromJson( - Map json) => - AnalyticsEventItemJson(); - -Map _$AnalyticsEventItemJsonToJson( - AnalyticsEventItemJson instance) => - {}; diff --git a/packages/plugins/plugin_firebase/pubspec.yaml b/packages/plugins/plugin_firebase/pubspec.yaml index 22bc644..1d4f7b3 100644 --- a/packages/plugins/plugin_firebase/pubspec.yaml +++ b/packages/plugins/plugin_firebase/pubspec.yaml @@ -21,7 +21,6 @@ dependencies: dev_dependencies: build_runner: ^2.3.3 - json_serializable: ^6.6.0 flutter_test: sdk: flutter flutter_lints: ^2.0.0