Feat/sdk setup for migrations - #68
Conversation
SikoraKam
left a comment
There was a problem hiding this comment.
Good work but it requires some refactor and clarifications.
Besides comments to specific places I have two general requests.
- Add documentation to pr which will describe each new field, each new setter and how to use it and what are the benefits. Move some comments documenting whole process from code to that documentation
- These code starts to becoming messy and and only understandable to ai. We need to keep separate logic for analytics, matching and now data collection as strictly as possible. Avoid mixing modules and long data flow between a few functions/hooks.
Please look for some refactor options besides these mentioned in comments
| @@ -10,11 +12,35 @@ export const sendEvent = async ({ | |||
| appID, | |||
| deviceId, | |||
There was a problem hiding this comment.
how we will treat deviceId now? is it still needed?
There was a problem hiding this comment.
Yes, it is still at fiew points:
- deviceId will be added to every event, also to purchase event. Thanks to this we are able to connect install from specific campain with other events. That enables us to count ROAS for specific campain. It is part of MMP requirements.
But you can ask if any other ids that we collect wouldn't be better for that. After some analysis i came to the conclusion that none of other ids like IDFV or AAID is as safe to match events with install as deviceId is because deviceId is set always regardless of consents.
- There is always possibility that other id's will never be set because of some consents or lack of informations from app host. But deviceId can still be used to safely match all of events to one specific user
| // Android advertising ID — feeds the backend's deterministic device_uuid. | ||
| export const getAaid = async (): Promise<string | undefined> => { | ||
| if (Platform.OS !== "android") return undefined; | ||
| if (manualAdvertisingId) return manualAdvertisingId; | ||
| const rawId = await fetchRawAdvertisingId(); | ||
| applyAaidAutoConsent(rawId); | ||
| if (!rawId || rawId === AD_ID_OPT_OUT) return undefined; | ||
| return rawId; | ||
| }; | ||
|
|
||
| // iOS advertising ID — ad-attribution signal only, does not feed device_uuid (IDFV does). | ||
| export const getIdfa = async (): Promise<string | undefined> => { |
There was a problem hiding this comment.
I don't know what is device_uuid - the only place where this name exists are these comments
There was a problem hiding this comment.
Device_uuid is concept that should be implemented in future backend changes. Backend will collect AAID for android or IDFV for IOS, then normalize and hash this id. It will happen for both data collected from our sdk and data send by migration process. Thanks to this we will be able to match same device from previous deeplink software as apps flyer with our id. Both ids themselves can be equal, but different software can pass in different formatting for example camelcase etc. For now it's just a concept that still need to be specified, so i will get rid of this from comments so it will not be misleading.
To easily follow the changes and review them, I recommend going commit by commit instead of file by file.
This version is still open to suggestions and possible changes, so if something needs adjusting / you have objections, feel free to let me know.
In
examples/expo-bareI'm leaving an app for testing the added functionality, and below is a short overview of what was added there:device_iddevice_idpresent, the same after an app restart (persisted)customer_user_idcustomer_user_id: "test-user-123"in the next eventidfvon iOS always;aaidon Android (real device, not an emulator — emulators sometimes return zeros);idfaon iOS only after ATT consentshouldRequestTrackingPermission: truein the config (add it temporarily toApp.tsxto test)att_statusin the event isgranted/denied, and with no extra actionconsent.ad/consent.trackingare set too (source: "att")setTrackingAuthorizationStatus(override)att_statusin the next event changes immediately;consentupdates as well (same mechanism as #4, just forced manually)setAdvertisingId(override)aaid/idfa(depending on the platform) =11111111-2222-3333-4444-555555555555in the next event, the native API is no longer queriedaaid=undefinedin the event (sentinel filtered out),consent.ad: false, source: "aaid-optout"without calling anything manuallysetConsentconsent: { ad, analytics, tracking, source: "manual", updatedAt: <timestamp> }in the next eventlogConversionevent_name: "purchase",revenue: 9.99,currency: "USD",product_id: "test_sku_1",quantity: 1,transaction_id: "test-txn-001"app_version/build_numberapp.json/the native build (changeversion/buildNumberinapp.json, rebuild, verify they change)os_version/localeos_versionmatching the system,locale= an array withlanguageTag; change the system language and verify it changes after a restartsession_id+ rotation after 30 minsession_id→ return to the same event without backgrounding → samesession_id. Then: background the app (home button), wait — temporarily lowerSESSION_TIMEOUT_MSinpackages/react-native-detour/src/analytics/hooks/useSessionTracking.tsxto e.g. 10s just for this test, rebuild, background for >10s, come back, fire an eventsession_id. After returning from a background longer than the timeout: a newsession_id. Remember to revert the timeout change after the testutm_source/utm_medium/utm_campaign— dev builds usually have no referrer (see the example's README)match-linkcontainsutm: {...}isLinkProcessed: true,type/url/routeget populated