chore(runway): cherry-pick fix: backfill-consent-event cp-7.73.0#28530
Merged
Conversation
) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> Social login (Google / Apple) users who completed onboarding before the `ANALYTICS_PREFERENCE_SELECTED` event was emitted on the marketing-consent screen never had that event fired for them. This PR introduces a one-time post-rehydration backfill so those users are counted correctly in analytics. **How it works (three-step design kept intentionally pure):** 1. **Migration 131** – runs at startup before the Redux store is live. If the persisted state contains a `SeedlessOnboardingController.authConnection` value, it writes a marker into `onboarding.seedless.pendingSocialLoginMarketingConsentBackfill`. The migration never fires analytics itself; it only stamps the persisted state so the side effect can be done safely after rehydration. 2. **Redux slice** – a new `SET_PENDING_SOCIAL_LOGIN_MARKETING_CONSENT_BACKFILL` action/reducer/selector manages the marker in `state.onboarding.seedless`. 3. **Saga** – `backfillSocialLoginMarketingConsent` runs once inside `startAppServices` (after `setAppServicesReady`). It reads the marker from the live store, fires `ANALYTICS_PREFERENCE_SELECTED` with `saveDataRecording: true`, calls `updateDataRecordingFlag`, and clears the marker. If the marketing consent is no longer enabled at run time (e.g. user toggled it off between migrations) the marker is cleared without sending any analytics. If `trackEvent` throws, the marker is left in place so a future run can retry. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: One-time marketing consent analytics backfill for social login users Background: Given I have a device with a previously installed version of MetaMask Mobile And I am a social login (Google or Apple) user And I previously accepted marketing data collection during onboarding Scenario: backfill event fires once on first launch after upgrade Given the app has not yet run migration 129 And state.security.dataCollectionForMarketing is true And state.engine.backgroundState.SeedlessOnboardingController.authConnection is "google" When user launches the app and the store rehydrates Then migration 129 sets onboarding.seedless.pendingSocialLoginMarketingConsentBackfill to "google" And the backfill saga fires an ANALYTICS_PREFERENCE_SELECTED event with has_marketing_consent true And the pending marker is cleared to null And on subsequent app launches no duplicate event is fired Scenario: backfill is skipped when user has opted out of marketing consent Given state.security.dataCollectionForMarketing is false And state.engine.backgroundState.SeedlessOnboardingController.authConnection is "google" When user launches the app and the store rehydrates Then migration 129 does NOT set the pending marker And no ANALYTICS_PREFERENCE_SELECTED event is fired Scenario: stale marker is cleared without analytics when consent is revoked before launch Given the pending marker was set in a previous session (e.g. "google") And the user has since revoked marketing consent (dataCollectionForMarketing is false) When the app launches and the saga runs Then the pending marker is cleared to null And no ANALYTICS_PREFERENCE_SELECTED event is fired ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] 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). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new persisted onboarding marker, a state migration, and a login-triggered saga that sends analytics/updates consent flags; mistakes could cause missed or duplicate analytics and unexpected consent state changes after rehydration. > > **Overview** > Adds a one-time *post-rehydration* analytics backfill for legacy social login (Google/Apple) users who never emitted `ANALYTICS_PREFERENCE_SELECTED` for marketing consent. > > This introduces a new onboarding state marker (`pendingSocialLoginMarketingConsentBackfill`) with action/reducer/selector support, sets it via new `migration 131` based on `SeedlessOnboardingController.authConnection`, and runs a new `backfillSocialLoginMarketingConsentSaga` after `LOGIN` to optionally query OAuth marketing opt-in, emit the analytics identify/event (with `saveDataRecording: true`), update recording via `updateDataRecordingFlag`, then clear the marker and sync `setDataCollectionForMarketing`. > > Wallet deletion now also clears the marker, and tests were added/updated across onboarding reducer/selectors, migrations, and sagas. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2a0bacd. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Contributor
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
Contributor
🔍 Smart E2E Test Selection⏭️ Smart E2E selection skipped - skip-smart-e2e-selection label found All E2E tests pre-selected. |
Contributor
|
✅ E2E Fixture Validation — Schema is up to date |
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Description
Social login (Google / Apple) users who completed onboarding before the
ANALYTICS_PREFERENCE_SELECTEDevent was emitted on themarketing-consent
screen never had that event fired for them. This PR introduces a
one-time
post-rehydration backfill so those users are counted correctly in
analytics.
How it works (three-step design kept intentionally pure):
Migration 131 – runs at startup before the Redux store is live.
If the
persisted state contains a
SeedlessOnboardingController.authConnectionvalue, it writes a
marker into
onboarding.seedless.pendingSocialLoginMarketingConsentBackfill.The migration never fires analytics itself; it only stamps the persisted
state so the side effect can be done safely after rehydration.
Redux slice – a new
SET_PENDING_SOCIAL_LOGIN_MARKETING_CONSENT_BACKFILLaction/reducer/selector manages the marker in
state.onboarding.seedless.Saga –
backfillSocialLoginMarketingConsentruns once insidestartAppServices(aftersetAppServicesReady). It reads the markerfrom
the live store, fires
ANALYTICS_PREFERENCE_SELECTEDwithsaveDataRecording: true, callsupdateDataRecordingFlag, and clearsthe
marker. If the marketing consent is no longer enabled at run time (e.g.
user
toggled it off between migrations) the marker is cleared without sending
any
analytics. If
trackEventthrows, the marker is left in place so afuture
run can retry.
Changelog
CHANGELOG entry: null
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Before
After
Pre-merge author checklist
Docs and MetaMask Mobile
Coding
Standards.
if applicable
guidelines).
Not required for external contributors.
Pre-merge reviewer checklist
app, test code being changed).
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
Note
Medium Risk
Adds a new persisted onboarding marker, a state migration, and a
login-triggered saga that sends analytics/updates consent flags;
mistakes could cause missed or duplicate analytics and unexpected
consent state changes after rehydration.
Overview
Adds a one-time post-rehydration analytics backfill for legacy
social login (Google/Apple) users who never emitted
ANALYTICS_PREFERENCE_SELECTEDfor marketing consent.This introduces a new onboarding state marker
(
pendingSocialLoginMarketingConsentBackfill) withaction/reducer/selector support, sets it via new
migration 131basedon
SeedlessOnboardingController.authConnection, and runs a newbackfillSocialLoginMarketingConsentSagaafterLOGINto optionallyquery OAuth marketing opt-in, emit the analytics identify/event (with
saveDataRecording: true), update recording viaupdateDataRecordingFlag, then clear the marker and syncsetDataCollectionForMarketing.Wallet deletion now also clears the marker, and tests were
added/updated across onboarding reducer/selectors, migrations, and
sagas.
Reviewed by Cursor Bugbot for commit
2a0bacd. Bugbot is set up for automated
code reviews on this repo. Configure
here.