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
360 stars 185 forks source link

@segment/analytics-react-native-plugin-braze - Invariant Violation: `new NativeEventEmitter()` requires a non-null argument., #888

Closed Jack-Gill-TH closed 3 months ago

Jack-Gill-TH commented 11 months ago

Hello! I'm hoping someone might be able to help me with an issue I'm experiencing while trying to integrate the Braze plugin. The app I'm using already uses segment and the segment firebase plugin successfully, and I am able to follow all the steps that are outlined in the Segment/Braze documentation for integrating the Braze SDK and the Braze Segment plugin. Everything works correctly for Android, however it does not work on iOS.

The app builds and runs fine on iOS with all of the native Braze install steps. However, as soon as I add the Braze plugin import to the JavaScript, it causes the app to freeze right after the bundle finishes loading. I also get a new error reported in Metro:


ERROR Invariant Violation: new NativeEventEmitter() requires a non-null argument., js engine: hermes WARN Module RNEventEmitter requires main queue setup since it overrides constantsToExport but doesn't implement requiresMainQueueSetup. In a future release React Native will default to initializing all native modules on a background thread unless explicitly opted-out of. WARN Module RNLocalization requires main queue setup since it overrides constantsToExport but doesn't implement requiresMainQueueSetup. In a future release React Native will default to initializing all native modules on a background thread unless explicitly opted-out of. ERROR Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native., js engine: hermes ERROR Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native., js engine: hermes


Specifically, the mention of 'Invariant Violation: new NativeEventEmitter()' and the 'Invariant Violation: Module AppRegistry is not a registered callable module' is new.

I think it's likely that this relates to incompatibility between the new segment libraries and my app's RN version (which is embarrassingly old) but if anyone has any insight it would be much appreciated.

Here is a list of what I believe are the relevant dependencies:

"@braze/react-native-sdk": "^7.0.0",
"@react-native-firebase/analytics": "^18.1.0",
"@react-native-firebase/app": "^18.1.0",
"@segment/analytics-react-native": "^2.15.0",
"@segment/analytics-react-native-plugin-braze": "^0.5.4",
"@segment/analytics-react-native-plugin-firebase": "^0.3.9",
"@segment/sovran-react-native": "1.0.4",
"react-native": "0.68.7",
"react-native-get-random-values": "^1.9.0",
Jack-Gill-TH commented 11 months ago
Screenshot 2023-10-11 at 13 42 02

I noticed in the Braze documentation that as of 6.0.0 they require RN 0.70 or higher, so I tried downgrading to "@braze/react-native-sdk": "5.2.0" but got the same result.

Also, the new architecture is disabled in my app.

Jack-Gill-TH commented 11 months ago

I thought I might try adding the import to one of our existing app components and trying to run the unit tests for that component - it fails with this output:

Summary of all failing tests FAIL app/scenes/Account/tests/Account.test.js ● Test suite failed to run

TypeError: Super expression must either be null or a function

  at _inherits (node_modules/@babel/runtime/helpers/inherits.js:5:11)
  at node_modules/@segment/analytics-react-native-plugin-braze/lib/commonjs/BrazePlugin.js:59:26
  at Object.<anonymous> (node_modules/@segment/analytics-react-native-plugin-braze/lib/commonjs/BrazePlugin.js:317:2)
  at Object.<anonymous> (node_modules/@segment/analytics-react-native-plugin-braze/lib/commonjs/index.ts:1:1)
oscb commented 11 months ago

@Jack-Gill-TH thanks for the report. I'm not quite sure what's happening here. It all points out to a possible incompatibility between braze - segment -your app. I know you are on a slightly older version of RN but I wouldn't expect that to be an issue as we are using 0.69 in the example in this repo and 0.71 in our other samples with Braze.

The plugin right now is capped to v5 of Braze's SDK so downgrading is a good step.

The error itself gives me the impression something might be off in the Braze SDK integration itself, as we don't directly call the NativeEventEmitter. Skimming through Braze's code: https://github.com/braze-inc/braze-react-native-sdk/blob/4ef01ede9c36a6f557d25cf7c704271c54d99a40/src/braze.js#L37C46-L37C46 It might be due to the bridge itself not being registered correctly in iOS. Can you try cleaning your pod files and your iOS build and retrying?

Jack-Gill-TH commented 11 months ago

Hi @oscb thanks so much for taking the time to respond!

I've commented out the 'new NativeEventEmitter' line that you pointed to in the Braze code and I can confirm that that's the problematic line, the app finishes bundling and no longer freezes at the splash screen when that line in removed (but obviously the Braze integration doesn't work!)

After each change I make I remove and reinstall my node modules and pods, and run Product -> Clean in Xcode - is there anything else I should be doing to clean up potentially cached files?

Here are my AppDelegate header and body files, I've been trying to figure out if there's an obvious difference between them and the ones in your example project, but I'd definitely appreciate you taking a look:

https://drive.google.com/drive/folders/1hRVjZYsGNHjFJwZRbIOppcZQV-Htb-KZ?usp=sharing

I've also included a screenshot of the iOS device log, after I set the Braze logging to debug - nothing seems obviously amiss to me there.

Jack-Gill-TH commented 11 months ago

Also, these AppDelegate files are very old and cluttered, apologies for that 😅

Jack-Gill-TH commented 11 months ago

Also, I've raised a ticket on the braze-react-native-sdk github, as it seems like this is more closely related to their code! https://github.com/braze-inc/braze-react-native-sdk/issues/233

A little bit of extra info: If I add a new bit of code to the constructor of my main App file to import NativeModules.BrazeReactBridge and create a NativeEventEmitter with it, it does not throw an error. Also, I can log out the BrazeReactBridge and see that it is NOT null, so it seems like some kind of race condition? The BrazeReactBridge is null when the Braze class from your sdk is instantiated.

hvardhan-unth commented 3 months ago

Addresses in PR #969