Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expo Notifications crashes app on reload #15788

Closed
u840903 opened this issue Jan 4, 2022 · 40 comments · Fixed by #17285
Closed

Expo Notifications crashes app on reload #15788

u840903 opened this issue Jan 4, 2022 · 40 comments · Fixed by #17285
Assignees

Comments

@u840903
Copy link

u840903 commented Jan 4, 2022

Summary

Expo Notifications 0.14.0 will crash an expo-dev-client build on an Ios device on app reload.

  1. Open the app on the device.
  2. Hit "r" in the terminal.

The app will crash with...

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error when sending event: onDevicePushToken with body: {
    devicePushToken = ***ACTUAL TOKEN REMOVED***;
}. Bridge is not set. This is probably because you've explicitly synthesized the bridge in EXReactNativeEventEmitter, even though it's inherited from RCTEventEmitter.'

The app does not crash when using Expo Go.

Somewhat similar issue.
#3276

Managed or bare workflow? If you have ios/ or android/ directories in your project, the answer is bare!

managed

What platform(s) does this occur on?

iOS

SDK Version (managed workflow only)

44

Environment

Expo CLI 5.0.3 environment info:
System:
OS: macOS 12.1
Shell: 5.8 - /bin/zsh
Binaries:
Node: 16.13.0 - ~/.nvm/versions/node/v16.13.0/bin/node
Yarn: 1.22.17 - ~/.nvm/versions/node/v16.13.0/bin/yarn
npm: 8.3.0 - ~/.nvm/versions/node/v16.13.0/bin/npm
Managers:
CocoaPods: 1.11.2 - /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 21.2, iOS 15.2, macOS 12.1, tvOS 15.2, watchOS 8.3
IDEs:
Xcode: 13.2.1/13C100 - /usr/bin/xcodebuild
npmPackages:
expo: ~44.0.0 => 44.0.3
react: 17.0.1 => 17.0.1
react-dom: 17.0.1 => 17.0.1
react-native: 0.64.3 => 0.64.3
react-native-web: 0.17.1 => 0.17.1
npmGlobalPackages:
eas-cli: 0.43.0
expo-cli: 5.0.3
Expo Workflow: managed

Reproducible demo

import {View} from 'react-native';
import {useEffect} from 'react';
import * as Notifications from 'expo-notifications';

export default function App() {
    useEffect(() => {
        const subscription = Notifications.addNotificationResponseReceivedListener(response => {});
        return () => subscription.remove();
    }, []);
    return <View />
}
@u840903 u840903 added the needs validation Issue needs to be validated label Jan 4, 2022
@u840903 u840903 changed the title Expo Notifications craches app on reload Expo Notifications crashes app on reload Jan 4, 2022
@jparkrr
Copy link
Contributor

jparkrr commented Jan 18, 2022

This is also happening to me when I'm launching various builds using QR codes in a custom dev-client.

@apedroferreira
Copy link

apedroferreira commented Jan 24, 2022

does anyone know of a temporary workaround?
this is a really bad issue, ever since i updated to SDK44 i can't debug or reload my app in dev in iOS because of this....

@Stevemoretz
Copy link

Stevemoretz commented Jan 26, 2022

For me it is :

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error when sending event: onHandleNotification with body:

I'm sending local push notifications, and onHandler seems to cause this.

@Stevemoretz
Copy link

Just to verify that, this exactly is the same problem which occurs only after the reload, but for me it is about onHandleNotification probably because I'm not using onDevicePushToken so yeah this is the same issue.

And it's really serious!

@magiskaoskar
Copy link

Just importing import * as Notifications from 'expo-notifications'; is enough for my app to crash with this error.

@apedroferreira
Copy link

Just importing import * as Notifications from 'expo-notifications'; is enough for my app to crash with this error.

yep same exact thing for me

@Bashin
Copy link

Bashin commented Feb 7, 2022

Just importing import * as Notifications from 'expo-notifications'; is enough for my app to crash with this error.

Same here.
RN0.64.3 with expo modules

@opeah
Copy link

opeah commented Feb 7, 2022

Same here.
RN 0.64.3 and Expo 44.0.6

@ironmanromeo
Copy link

Same here.
RN 0.64.3 and Expo 44.0.5

@nicib83
Copy link

nicib83 commented Feb 15, 2022

same here:

  • tried with a new iOS bundle ID, and new notifications certificates, the problem occurs as soon as notifications are approved for the bundle ID, then its there
  • error is (usually) reload on console, reload on menu, sometime just opening of menu is enough
  • but import * as Notifications from 'expo-notifications' is not enough, i also need to use it, can be trivial, like console.log(Notifications), this is probably due to code optimization

@Stevemoretz
Copy link

For anyone having this issue, it has nothing to do with your notification configuration keys and push notification at all, I'm basically using it as just a local notification builder and still get that error not even using the getPushToken method.

@ianatha
Copy link

ianatha commented Feb 19, 2022

following -- same here at RN 0.64.3 & Expo 44.0.6

    initialProps =     {
    };
    rootTag = 11;
})
2022-02-19 13:06:29.117761+0200 seahorse[499:11224] [javascript] Running "main" with {"rootTag":11,"initialProps":{}}
2022-02-19 13:06:29.137864+0200 seahorse[499:10205] *** Assertion failure in -[RCTEventEmitter sendEventWithName:body:](), /Users/REDACTED/seahorse/node_modules/react-native/React/Modules/RCTEventEmitter.m:58
2022-02-19 13:06:29.139394+0200 seahorse[499:10205] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error when sending event: onDevicePushToken with body: {
    devicePushToken = REDACTED;
}. Bridge is not set. This is probably because you've explicitly synthesized the bridge in EXReactNativeEventEmitter, even though it's inherited from RCTEventEmitter.'
*** First throw call stack:
(0x1822e904c 0x19a95df54 0x183ba2834 0x102358f18 0x102657b50 0x102657404 0x1021f4a14 0x10223cf6c 0x102235ad8 0x10223595c 0x102233cc4 0x102235a1c 0x186d5f338 0x1022357d8 0x102235b4c 0x103a986d4 0x103a9a3b4 0x103aaa898 0x1822a1cd4 0x18225beac 0x18226f3b8 0x19dbff38c 0x184c0f6a8 0x18498e7f4 0x1021d2700 0x1038cda24)
libc++abi: terminating with uncaught exception of type NSException
dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error when sending event: onDevicePushToken with body: {
    devicePushToken = REDACTED;
}. Bridge is not set. This is probably because you've explicitly synthesized the bridge in EXReactNativeEventEmitter, even though it's inherited from RCTEventEmitter.'
terminating with uncaught exception of type NSException
(lldb) ```

@cyrusgeyer
Copy link

cyrusgeyer commented Feb 26, 2022

Seems to be fixed in 0.14.1
Edit: it's not fixed.

@benrudolph
Copy link

benrudolph commented Feb 26, 2022

we've been using 0.14.1, and it hasn't been fixed for us. we've written a hacky shim to get around this in dev

@Stevemoretz
Copy link

we've been using 0.14.1, and it hasn't been fixed for me. we've written a hacky shim to get around this in dev

Could be nice if you would have shared your workaround

@benrudolph
Copy link

ah yeah i mean it's just do not import if on iOS and __DEV__

import { Platform } from 'react-native';

// HACK: shim all `expo-notifcation` calls as it breaks development for iOS.
// https://github.com/expo/expo/issues/15788
const IOS_NOTIFICATION_ISSUE = Platform.OS === 'ios' && __DEV__;

export let setNotificationHandler = (...args: any[]) => null;
...
if (!IOS_NOTIFICATION_ISSUE)  {
  const ExpoNotifications = require('expo-notifications');
  setNotificationHandler = ExpoNotifications.setNotificationHandler;
  ...
}

@Stevemoretz
Copy link

ah yeah i mean it's just do not import if on iOS and __DEV__

import { Platform } from 'react-native';

// HACK: shim all `expo-notifcation` calls as it breaks development for iOS.
// https://github.com/expo/expo/issues/15788
const IOS_NOTIFICATION_ISSUE = Platform.OS === 'ios' && __DEV__;

export let setNotificationHandler = (...args: any[]) => null;
...
if (!IOS_NOTIFICATION_ISSUE)  {
  const ExpoNotifications = require('expo-notifications');
  setNotificationHandler = ExpoNotifications.setNotificationHandler;
  ...
}

Thanks for sharing! I think that's actually the best workaround anyone can come up with right now.

@hirbod
Copy link
Contributor

hirbod commented Mar 4, 2022

I can confirm this issue.
@brentvatne ?

@apedroferreira
Copy link

apedroferreira commented Mar 6, 2022

still an issue with the latest versions of expo-notifications (0.14.1) and expo-dev-client (0.8.4)

@delgiudices
Copy link

Experiencing the same problem

@intergalacticspacehighway
Copy link
Contributor

Just importing import * as Notifications from 'expo-notifications'; is enough for my app to crash with this error.

Did some digging, found that this line leads to crash on dev client reloads. This line is calling registerForRemoteNotifications on the native side which emits event to JS side at some point. This assertion is crashing the app.

Attaching some logs when it crashes. It tries to send the event but the bridge is not set. I am not sure why the bridge could be nil, maybe some race condition, will have to dig more 😅

2022-03-17 14:49:34.230406+0530 Showtime[24248:5821450] [javascript] Running "main" with {"rootTag":31,"initialProps":{}}
2022-03-17 14:49:34.300126+0530 Showtime[24248:5820874] *** Assertion failure in -[RCTEventEmitter sendEventWithName:body:](), /Users/nishanbende/Desktop/nishan/work/showtime-frontend/node_modules/react-native/React/Modules/RCTEventEmitter.m:58
2022-03-17 14:49:34.300927+0530 Showtime[24248:5820874] DevLauncher tries to handle uncaught exception: Error when sending event: onDevicePushToken with body: {
    devicePushToken = 2f21636b42bd83caf8d4f79604849b79e0e36488bee3cf318c11dca46c09b0bb;
}. Bridge is not set. This is probably because you've explicitly synthesized the bridge in EXReactNativeEventEmitter, even though it's inherited from RCTEventEmitter.
2022-03-17 14:49:34.310305+0530 Showtime[24248:5820874] Stack Trace: (
    "0   CoreFoundation                      0x0000000180a29110 E2F84645-2905-31EF-8EC7-3CC19C3CDDB3 + 626960",
    "1   libobjc.A.dylib                     0x0000000199279d64 objc_exception_throw + 60",
    "2   Foundation                          0x00000001822e5504 925A43CD-EAF2-3161-9378-3ED87468301D + 1246468",
    "3   Showtime                            0x00000001049681d4 -[RCTEventEmitter sendEventWithName:body:] + 452",
    "4   Showtime                            0x000000010509e8d0 __copy_helper_block_e8_32s40b48b56w + 23560",
    "5   Showtime                            0x000000010509e184 __copy_helper_block_e8_32s40b48b56w + 21692",
    "6   Showtime                            0x0000000104187614 -[EXLegacyAppDelegateWrapper application:didRegisterForRemoteNotificationsWithDeviceToken:] + 324",
    "7   Showtime                            0x00000001041d27a8 $sTa.171 + 32",
    "8   Showtime                            0x00000001041cae40 $sSo13UIApplicationCSo6NSDataCIegyy_AB10Foundati
2022-03-17 14:49:34.310918+0530 Showtime[24248:5820874] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error when sending event: onDevicePushToken with body: {
    devicePushToken = 2f21636b42bd83caf8d4f79604849b79e0e36488bee3cf318c11dca46c09b0bb;
}. Bridge is not set. This is probably because you've explicitly synthesized the bridge in EXReactNativeEventEmitter, even though it's inherited from RCTEventEmitter.'
*** First throw call stack:
(0x180a290fc 0x199279d64 0x1822e5504 0x1049681d4 0x10509e8d0 0x10509e184 0x104187614 0x1041d27a8 0x1041cae40 0x1041caca0 0x1041c8ebc 0x1041cad78 0x1854b6284 0x1041cab04 0x1041caeb4 0x108eb46d4 0x108eb63b4 0x108ec6898 0x1809e1d84 0x18099bf5c 0x1809af468 0x19c55338c 0x1833525d0 0x1830d0f74 0x1040bfa60 0x108bd1aa4)
libc++abi: terminating with uncaught exception of type NSException
dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib:/Developer/Library/PrivateFrameworks/GPUTools.framework/libglInterpose.dylib
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error when sending event: onDevicePushToken with body: {
    devicePushToken = 2f21636b42bd83caf8d4f79604849b79e0e36488bee3cf318c11dca46c09b0bb;
}. Bridge is not set. This is probably because you've explicitly synthesized the bridge in EXReactNativeEventEmitter, even though it's inherited from RCTEventEmitter.'
terminating with uncaught exception of type NSException

@hirbod
Copy link
Contributor

hirbod commented Mar 17, 2022

@intergalacticspacehighway when you say the bridge is not set, this reminds me of:
mrousavy/react-native-mmkv#294

As soon as dev-client reloads, it crashes mmkv as well. Maybe these issues are related.

@apedroferreira
Copy link

apedroferreira commented Mar 18, 2022

Could it have to do with this issue? I do also have a warning log about the RCT bridge when I load the app. #14766

I remember fixing the RCT bridge warning message with some changes to AppDelegate mentioned here facebook/react-native#16376, but that still didn't fix this issue.

@robertherber
Copy link
Contributor

robertherber commented Apr 14, 2022

I solved it by replacing all expo-notifications imports with this (which just mocks expo-notifications for iOS in dev-mode):

./expo-notifications.js
// eslint-disable-next-line no-undef, @typescript-eslint/no-var-requires, import/order
const { Platform } = require('react-native');

/** @type {typeof import('expo-notifications/src/index')} */
const mockedNotifications = {
  getDevicePushTokenAsync: (() => Promise.resolve({})),
  getExpoPushTokenAsync: (() => Promise.resolve({})),
  getPresentedNotificationsAsync: (() => Promise.resolve({})),
  presentNotificationAsync: (() => Promise.resolve({})),
  dismissNotificationAsync: (() => Promise.resolve({})),
  dismissAllNotificationsAsync: (() => Promise.resolve({})),
  getNotificationChannelsAsync: (() => Promise.resolve({})),
  getNotificationChannelAsync: (() => Promise.resolve({})),
  setNotificationChannelAsync: (() => Promise.resolve({})),
  deleteNotificationChannelAsync: (() => Promise.resolve({})),
  getNotificationChannelGroupsAsync: (() => Promise.resolve({})),
  getNotificationChannelGroupAsync: (() => Promise.resolve({})),
  setNotificationChannelGroupAsync: (() => Promise.resolve({})),
  deleteNotificationChannelGroupAsync: (() => Promise.resolve({})),
  getBadgeCountAsync: (() => Promise.resolve({})),
  setBadgeCountAsync: (() => Promise.resolve({})),
  getAllScheduledNotificationsAsync: (() => Promise.resolve({})),
  scheduleNotificationAsync: (() => Promise.resolve({})),
  cancelScheduledNotificationAsync: (() => Promise.resolve({})),
  cancelAllScheduledNotificationsAsync: (() => Promise.resolve({})),
  getNotificationCategoriesAsync: (() => Promise.resolve({})),
  setNotificationCategoryAsync: (() => Promise.resolve({})),
  deleteNotificationCategoryAsync: (() => Promise.resolve({})),
  getNextTriggerDateAsync: (() => Promise.resolve({})),
  useLastNotificationResponse: (() => Promise.resolve({})),
  setAutoServerRegistrationEnabledAsync: (() => Promise.resolve({})),
  registerTaskAsync: (() => Promise.resolve({})),
  unregisterTaskAsync: (() => Promise.resolve({})),
  addPushTokenListener: (() => Promise.resolve({ remove: () => {} })),
  removePushTokenSubscription: (() => Promise.resolve({})),
  addNotificationReceivedListener: (() => Promise.resolve({ remove: () => {} })),
  addNotificationsDroppedListener: (() => Promise.resolve({ remove: () => {} })),
  addNotificationResponseReceivedListener: (() => Promise.resolve({ remove: () => {} })),
  removeNotificationSubscription: (() => Promise.resolve({})),
  getLastNotificationResponseAsync: (() => Promise.resolve({})),
  setNotificationHandler: (() => Promise.resolve({})),
  getPermissionsAsync: (() => Promise.resolve({})),
  requestPermissionsAsync: (() => Promise.resolve({})),
  usePermissions: (() => Promise.resolve({})),
  AndroidAudioContentType: {},
  AndroidAudioUsage: {},
  AndroidImportance: {},
  AndroidNotificationPriority: {},
  AndroidNotificationVisibility: {},
  DEFAULT_ACTION_IDENTIFIER: 'DEFAULT_ACTION_IDENTIFIER',
  IosAlertStyle: {},
  IosAllowsPreviews: {},
  IosAuthorizationStatus: {},
  NotificationTimeoutError: {},
};

// eslint-disable-next-line no-undef
const toExport = __DEV__ && Platform.OS === 'ios' ? { ...mockedNotifications, default: mockedNotifications } : require('expo-notifications');
// eslint-disable-next-line no-undef, @typescript-eslint/no-var-requires
// const toExport = require('expo-notifications');

/** @type {typeof import('expo-notifications/src/index')} */
module.exports = toExport; // eslint-disable-line functional/immutable-data, @typescript-eslint/no-var-requires

Just save it as a file locally and import from this instead of directly from expo-notifications. It mocks it specifically for iOS in dev mode so it doesn't crash (but is also obviously not usable) - in all other cases it uses expo-notifications as usual. Hope this can help someone until it's fixed! 👍

@JavaScriptJohn
Copy link

I am also having this issue on iOS using the dev client.

@ajsmth ajsmth self-assigned this Apr 19, 2022
@marcato15
Copy link

This is also a major issue for us.

@artvichi
Copy link

artvichi commented Apr 23, 2022

up, still persist. It fails for us in Prod release via EAS. I think it's critical issue

@hirbod
Copy link
Contributor

hirbod commented Apr 23, 2022

It got finally assigned to a dev, guess it will be fixed soon :)

@master-eugene
Copy link

not working for me as well! can't publish my application..

@hirbod
Copy link
Contributor

hirbod commented Apr 25, 2022

not working for me as well! can't publish my application..

You can publish. This crash only occurs while developing, not in a release build.

@master-eugene
Copy link

@hirbod it looks like this is not totally correct. Maybe somewhat with our setup, but in production it doesn't work as well, crashes the app and we can see the same error message in sentry. (we use eas build)

@hirbod
Copy link
Contributor

hirbod commented Apr 25, 2022

Are you reloading your app with expo-updates? Otherwise this should not happen. I only have this crash when I reload the app while developing @Eugene-Kai, not while in production

@master-eugene
Copy link

@hirbod good point! I found the issue, that was on our side. Thank you! It works in production

@itsramiel
Copy link

itsramiel commented Apr 25, 2022

I dont understand why expo is not addressing this issue. It is really frustrating developer experience not being able to reload ios devices. It has been there for 4 months. It seriously kills the will to develop

@brentvatne
Copy link
Member

@ajsmth is assigned to this and investigating. if you'd like to help out you can also investigate and open a pr :)

@itsramiel
Copy link

I wish I could : (

@brentvatne
Copy link
Member

hang tight, or look at #15788 (comment) and possibly try applying that suggestion to your project

lukmccall added a commit that referenced this issue Apr 29, 2022
# Why

Closes #15788.
Right now, modules have not been deallocated on the reload.

# How 

Remove cycle reference.

# Test plan 

- expo go ✅
lukmccall added a commit that referenced this issue Apr 29, 2022
Closes #15788.
Right now, modules have not been deallocated on the reload.

Remove cycle reference.

- expo go ✅
lukmccall added a commit that referenced this issue Apr 29, 2022
Closes #15788.
Right now, modules have not been deallocated on the reload.

Remove cycle reference.

- expo go ✅
@anhkieet
Copy link

Same here. But I got this issue when using expo-in-app-purchases

Screen Shot 2022-04-30 at 19 00 32

@kesha-antonov
Copy link
Contributor

Same here. But I got this issue when using expo-in-app-purchases

Screen Shot 2022-04-30 at 19 00 32

Same!
Did you find solution?

@hirbod
Copy link
Contributor

hirbod commented Apr 30, 2022

You guys should re-open a new ticket for this and provide a repro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet