From 7139a158dd855ab97af2822d40ab792d9d0b5ab8 Mon Sep 17 00:00:00 2001 From: Jony Bursztyn Date: Mon, 20 Jan 2025 15:07:08 +0000 Subject: [PATCH] fix: ensure marketing consent is explicitly tracked as boolean (#12926) ## **Description** Currently, when users decline marketing consent during onboarding, the `has_marketing_consent` property is not being set at all in the analytics. This creates inconsistent data where we can't properly track users who explicitly opted out of marketing. This PR modifies the OptinMetrics component to explicitly set `has_marketing_consent` to either `true` or `false` based on the user's choice, ensuring we have complete analytics data for all user decisions regarding marketing consent. ## **Related issues** Fixes: https://github.com/MetaMask/mobile-planning/issues/2086 ## **Manual testing steps** 1. Fresh install the app 2. Go through onboarding until you reach the "Help us improve MetaMask" screen 3. Test both scenarios: - Accept metrics but decline marketing consent checkbox - Accept both metrics and marketing consent 4. Verify in analytics that `has_marketing_consent` is properly set to `false` in first case and `true` in second case ## **Screenshots/Recordings** ### **Before** Analytics data missing `has_marketing_consent` property when user declines marketing consent ### **After** Analytics data showing explicit `has_marketing_consent: false` when user declines marketing consent ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- app/components/UI/OptinMetrics/index.js | 55 ++++++++++--------- app/components/UI/OptinMetrics/index.test.tsx | 2 + 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/app/components/UI/OptinMetrics/index.js b/app/components/UI/OptinMetrics/index.js index 58506d586b3..31a7812f9c8 100644 --- a/app/components/UI/OptinMetrics/index.js +++ b/app/components/UI/OptinMetrics/index.js @@ -337,23 +337,38 @@ class OptinMetrics extends PureComponent { isDataCollectionForMarketingEnabled, setDataCollectionForMarketing, } = this.props; + + // Set marketing consent trait based on user selection + const dataCollectionForMarketingTraits = { + has_marketing_consent: Boolean( + this.props.isDataCollectionForMarketingEnabled, + ), + }; + await metrics.enable(); - InteractionManager.runAfterInteractions(async () => { - // add traits to user for identification - if ( - isDataCollectionForMarketingEnabled === null && - setDataCollectionForMarketing - ) { - setDataCollectionForMarketing(false); - } + // Track the analytics preference event first + metrics.trackEvent( + metrics + .createEventBuilder(MetaMetricsEvents.ANALYTICS_PREFERENCE_SELECTED) + .addProperties({ + ...dataCollectionForMarketingTraits, + is_metrics_opted_in: true, + location: 'onboarding_metametrics', + updated_after_onboarding: false, + }) + .build(), + ); - // trait indicating if user opts in for data collection for marketing - let dataCollectionForMarketingTraits; - if (this.props.isDataCollectionForMarketingEnabled) { - dataCollectionForMarketingTraits = { has_marketing_consent: true }; - } + // Handle null case for marketing consent + if ( + isDataCollectionForMarketingEnabled === null && + setDataCollectionForMarketing + ) { + setDataCollectionForMarketing(false); + } + InteractionManager.runAfterInteractions(async () => { // consolidate device and user settings traits const consolidatedTraits = { ...dataCollectionForMarketingTraits, @@ -381,21 +396,7 @@ class OptinMetrics extends PureComponent { delay += eventTrackingDelay; }); } - this.props.clearOnboardingEvents(); - - // track event for user opting in on metrics and data collection for marketing - metrics.trackEvent( - metrics - .createEventBuilder(MetaMetricsEvents.ANALYTICS_PREFERENCE_SELECTED) - .addProperties({ - ...dataCollectionForMarketingTraits, - is_metrics_opted_in: true, - location: 'onboarding_metametrics', - updated_after_onboarding: false, - }) - .build(), - ); }); this.continue(); }; diff --git a/app/components/UI/OptinMetrics/index.test.tsx b/app/components/UI/OptinMetrics/index.test.tsx index 3072907108e..121a7a2e141 100644 --- a/app/components/UI/OptinMetrics/index.test.tsx +++ b/app/components/UI/OptinMetrics/index.test.tsx @@ -65,6 +65,7 @@ describe('OptinMetrics', () => { MetaMetricsEvents.ANALYTICS_PREFERENCE_SELECTED, ) .addProperties({ + has_marketing_consent: false, is_metrics_opted_in: true, location: 'onboarding_metametrics', updated_after_onboarding: false, @@ -75,6 +76,7 @@ describe('OptinMetrics', () => { deviceProp: 'Device value', userProp: 'User value', is_metrics_opted_in: true, + has_marketing_consent: false, }); }); });