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
357 stars 184 forks source link

BrazePlugin: Exception in HostFunction: Malformed calls from JS: field sizes are different after called identify #741

Closed sonnguyprophet closed 1 year ago

sonnguyprophet commented 1 year ago

I have integrated with the plugins below:

"@segment/analytics-react-native": "^2.8.0"
"@segment/analytics-react-native-plugin-appsflyer": "^0.4.0"
"@segment/analytics-react-native-plugin-braze": "^0.4.0"
"@segment/analytics-react-native-plugin-mixpanel": "^0.2.3"
  const segmentClient = createClient({
    writeKey: keys.SEGMENT_KEY,
    trackAppLifecycleEvents: true,
    trackDeepLinks: true,
  });
  segmentClient.add({
    plugin: new AppsflyerPlugin(),
  });
  segmentClient.add({ plugin: new BrazePlugin() });
  segmentClient.add({ plugin: new MixpanelPlugin() });

I got the error when fire identify with user info after the user sign up or sign in. And that makes other identify plugins (Mixpanel/Appsflyer/Segment) that were not fired too => user's events were lost on our destination dashboard.

Malformed calls from JS: field sizes are different.

[[121,121,121,89,89,89,91],[5,8,0,0,1,0,2],[[],["974dbef3-7f87-47b3-b386-5e95fa169f72",null],[2722,2000,1673421911098,false],[2675],[2730,1000,1673421911099,false],["{\"type\":\"log\",\"level\":\"info\",\"mode\":\"BRIDGE\",\"data\":[\"IDENTIFY event saved\",\"{\\\"traits\\\": {\\\"address\\\": {\\\"city\\\": \\\"Biloxi\\\", \\\"country\\\": \\\"US\\\", \\\"postalCode\\\": \\\"39532\\\", \\\"state\\\": \\\"MS\\\", \\\"street\\\": \\\"124 1 madison plz\\\"}, \\\"age\\\": 21, \\\"birthday\\\": \\\"January 9, 2002\\\", \\\"createdAt\\\": \\\"January 10, 2023\\\", \\\"email\\\": \\\"son.nguy+test134@gmail.com\\\", \\\"firstName\\\": \\\"Son\\\", \\\"lastName\\\": \\\"134\\\", \\\"phone\\\": \\\"2012232481\\\", \\\"userID\\\": \\\"974dbef3-7f87-47b3-sdf343-5e95fasdf9f72\\\"}, \\\"type\\\": \\\"identify\\\", \\\"userId\\\": \\\"974dbef3-7f87-47b3-sdf343-5e95fasdf9f72\\\"}\"]}",1]],14494]

it works well if I remove or comment this line segmentClient.add({ plugin: new BrazePlugin() });

Noted: It happened on some devices not all.

Steps to reproduce 1- Calling identify ({ identify } = useAnalytics()) with user info after sign up or sign in. Expected behavior Work well without error Actual behavior Error happened -> user's events lost Simulator Screen Shot - iPhone 14 Pro - 2023-01-11 at 14 25 54

sonnguyprophet commented 1 year ago

When I debugged identify.ts (@segment/analytics-react-native-plugin-braze) I have found that sometimes const data = new Date(payload.traits.birthday); returned NaN value when payload.traits.birthday with "MMMM D, YYYY" format. We use this format in web and mobile app and also worked for almost user profiles.

image

image

Sometimes we got this warning

WARN  Possible Unhandled Promise Rejection (id: 1):
Invariant Violation: ["<<NaN>>","<<NaN>>","<<NaN>>"] is not usable as a native method argument
Invariant Violation: ["<<NaN>>","<<NaN>>","<<NaN>>"] is not usable as a native method argument
    at invariant (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.prophetexchange.app:16645:26)
    at enqueueNativeCall (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.prophetexchange.app:17122:54)
    at nonPromiseMethodWrapper (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.prophetexchange.app:16820:78)
    at setDateOfBirth (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.prophetexchange.app:200839:35)
    at _default (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.prophetexchange.app:283730:51)
    at identify (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.prophetexchange.app:283691:34)

@oscb any advice or recommendation in this case? Thanks

oscb commented 1 year ago

@sonnguyprophet Sorry for the lack of responses, I've been busy with other projects but you did a great job at pinpointing the problem.

We do suggest in the traits documentation of Segment to use an ISO_8601 with all the dates in the Identify spec. It would be a hard and prone to errors for us to try to figure out the exact time format, although I'll make a note to add better error handling at this scenario so that you get a warning if the date is in a different format.

If your birthdays are in "MMMM D, YYYY" format I would suggest you parse it and convert it into standard date string before you make the identify calls, I can suggest day.js or date-fns for the parsing and conversion:

const birthday = getBirthday(); // However you are getting the birthdate for the user

identify('userID', { birthday: dayjs(birthday, 'MMMM D, YYYY').toISOString() }),

That way you can guarantee that the date is in the right format for Braze or any other plugins that might use it.

If you want the birthday to be correct only for Braze, but keep the same format you have everywhere else that's also possible. For that you would need to create plugin. That can also work, but if the above works for you I would strongly recommend it for better interoperability with any destinations.

Let us know if you need any help

sonnguyprophet commented 1 year ago

Thanks for your response @oscb. Actually, we stored the user's birthday like this 1993-08-09T00:00:00.000000Z but when we call identify we have converted it to 'MMMM D, YYYY' format like the image below image

Let us keep the pure value from our database to identify calls to fix this issue first and it will show like that in the user profile image

sonnguyprophet commented 1 year ago

Hi @oscb, I tried using ISO 8601, it worked but I have no idea why the user's birthday in Mixpanel is off by 1 day. More details are provided below.

I selected my DOB as 2002-01-31 (January 31, 2002) image

Segment display: image Braze display: image Mixpanel display: image