From 0f5eaabd976243163d71bc889dad35fafaa0ba70 Mon Sep 17 00:00:00 2001 From: Ahmed Al Amawi Date: Sun, 2 Aug 2026 12:47:11 -0400 Subject: [PATCH 1/2] fix: don't crash at import time when native modules are unavailable When the native module isn't linked (Expo Go, Jest, web bundles, a prebuild before pods are installed), NativeModules.IntercomEventEmitter is undefined and the module-scope constant reads in index.tsx (e.g. IntercomEventEmitter.UNREAD_COUNT_CHANGE_NOTIFICATION) throw at import time, crashing the app on boot. Fall back to an empty object so failure is deferred to actual API calls instead of the import. --- src/nativeModules.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/nativeModules.ts b/src/nativeModules.ts index c3f18b8a..68b5d957 100644 --- a/src/nativeModules.ts +++ b/src/nativeModules.ts @@ -8,8 +8,9 @@ function isTurboModuleAvailable(name: string) { } } -export const IntercomModule = isTurboModuleAvailable('IntercomModule') - ? require('./NativeIntercomSpec').default - : NativeModules.IntercomModule; +export const IntercomModule = + (isTurboModuleAvailable('IntercomModule') + ? require('./NativeIntercomSpec').default + : NativeModules.IntercomModule) ?? {}; -export const IntercomEventEmitter = NativeModules.IntercomEventEmitter; +export const IntercomEventEmitter = NativeModules.IntercomEventEmitter ?? {}; From 1c9a7c48b62680e2c5d6e3165a25a00ca5f447b8 Mon Sep 17 00:00:00 2001 From: Ahmed Al Amawi Date: Sun, 2 Aug 2026 12:54:09 -0400 Subject: [PATCH 2/2] test: cover nativeModules fallback when the native side is missing --- __tests__/nativeModules.test.ts | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 __tests__/nativeModules.test.ts diff --git a/__tests__/nativeModules.test.ts b/__tests__/nativeModules.test.ts new file mode 100644 index 00000000..61eb57d5 --- /dev/null +++ b/__tests__/nativeModules.test.ts @@ -0,0 +1,45 @@ +/** + * Tests that importing the native module bindings does not throw when the + * native side is unavailable (Expo Go, Jest, web bundles, prebuilds before + * pods are installed). + */ + +describe('nativeModules', () => { + afterEach(() => { + jest.resetModules(); + jest.dontMock('react-native'); + }); + + test('falls back to empty objects when native modules are missing', () => { + jest.doMock('react-native', () => ({ + NativeModules: {}, + TurboModuleRegistry: { get: () => null }, + })); + + let modules: typeof import('../src/nativeModules') | undefined; + expect(() => { + modules = require('../src/nativeModules'); + }).not.toThrow(); + + expect(modules?.IntercomModule).toEqual({}); + expect(modules?.IntercomEventEmitter).toEqual({}); + }); + + test('uses the registered native modules when they are available', () => { + const intercomModule = { initialize: jest.fn() }; + const intercomEventEmitter = { UNREAD_COUNT_CHANGE_NOTIFICATION: 'event' }; + + jest.doMock('react-native', () => ({ + NativeModules: { + IntercomModule: intercomModule, + IntercomEventEmitter: intercomEventEmitter, + }, + TurboModuleRegistry: { get: () => null }, + })); + + const modules = require('../src/nativeModules'); + + expect(modules.IntercomModule).toBe(intercomModule); + expect(modules.IntercomEventEmitter).toBe(intercomEventEmitter); + }); +});