segmentio / analytics-react-native

The hassle-free way to add analytics to your React-Native app.
https://segment.com/docs/sources/mobile/react-native/
MIT License
354 stars 182 forks source link

Alias is sent without proper context #860

Closed RohovDmytro closed 9 months ago

RohovDmytro commented 11 months ago

Steps to reproduce

  1. Open an app

  2. Crate Segment client:

    export const SEGMENT_CLIENT = createClient({
    writeKey: "***",
    autoAddSegmentDestination: true,
    flushAt: __DEV__ ? 999 : 10,
    trackAppLifecycleEvents: true,
    flushInterval: __DEV__ ? 60000 : 10000, // 10 seconds
    debug: __DEV__ ? true : false,
    collectDeviceId: true,
    trackDeepLinks: true,
    });
  3. alias & flush ASAP:

await SEGMENT_CLIENT.alias(id);
await SEGMENT_CLIENT.flush();
  1. Go to Debugger via Segment web interface.
  2. Observe:
    {
    "anonymousId": "****",
    "context": {
    "library": {
      "name": "unknown",
      "version": "unknown"
    }
    },
    "integrations": {},
    "messageId": "****",
    "originalTimestamp": "2023-07-25T17:28:18.612Z",
    "previousId": "1ea8acf3-b826-448b-8826-0193cf9860c7",
    "receivedAt": "2023-07-25T17:28:53.563Z",
    "sentAt": "2023-07-25T17:28:51.276Z",
    "timestamp": "2023-07-25T17:28:20.899Z",
    "type": "alias",
    "userId": "****",
    "writeKey": "****"
    }

Two many unknowns.

The following events do have proper context data, such as:

image

Expected behavior Have context with populated data.

Actual behavior No context data.

I have found this issue as a part of investigation why Segment reports more MTU that I expect. Not sure if it's related, but I can say that id used to alias was counted towards MTU, BUT also a user id which was later identified. So one user get tracked as 2 MTU after:

App Opened => Alias => Identify => 2 MTU

RohovDmytro commented 11 months ago

Feels related: https://github.com/segmentio/analytics-react-native/issues/449

RohovDmytro commented 11 months ago

Update an issue to indicate the flush is also being called, ASAP.

oscb commented 10 months ago

@RohovDmytro we're investigating this. It does sound related to the concurrency issues we've seen before.

2 things I might suggest:

Instead of sending the alias right away, send it after the analytics object reports everything ready. I don't think the alias is the problem here, but probably calling the flush right away circumvents the gate check for not sending data before everything is loaded (which is a bug):

SEGMENT_CLIENT.isReady.onChange((isReady) => {
  if (isReady) {
    void (async () => {
        await SEGMENT_CLIENT.alias(id);
        await SEGMENT_CLIENT.flush();
    })();
 });

If my theory is correct the problem might be flushing right away bypassing the check for readiness before uploading things to Segment. Is this flush 100% required for your use case? If not, I might suggest just calling alias then wait for an count/interval flush during the normal event capture, we also automatically do an upload right away when everything's ready so it should be pretty much immediate.

I'm also curious about your scenario

App Opened => Alias => Identify => 2 MTU

I think it makes sense that this is being reported as 2 MTU. I might suggest switching the order of those two:

App Opened => Identify => Alias

Alias is meant to link 2 userIds, if you use it before an identify it will pretty much work the same way as an identify, just setting the first userId, the identify happening afterwards overrides this first userId then. At least If I'm understanding this correctly.

Putting the identify first should be able to set the starting userId and then the alias afterwards should contain the previousId property where you can correlate to a previous user so that your MTU shows only 1 user.

Feel free to contact friends@segment.com, they should be able to help you out with more specific scenarios like these

GlebUsDA commented 10 months ago

It looks like the source of issue related to pendingEvents array in SegmentClient. When the events appears in this queue there are no context for them (that should came from applyRawEventData func) because SegmentClient was not Ready yet. Once SegmentClient is Ready it just sends events from pendingEvents without call applyRawEventData again. In my case that's why events sometimes appears without proper context and even with different anonymousId.

oscb commented 9 months ago

v2.16.1 should fix this. Let us know if it doesn't.