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

Android: onForegroundEvent not listening to onPress Event #621

Closed
quicksilverr opened this issue Dec 20, 2022 · 56 comments · Fixed by #720 or #1127
Closed

Android: onForegroundEvent not listening to onPress Event #621

quicksilverr opened this issue Dec 20, 2022 · 56 comments · Fixed by #720 or #1127

Comments

@quicksilverr
Copy link

Hey, thanks for building such a cool package for handling notifications in RN.

The current issue that I'm facing is that, if the app is in the foreground state and I click on the notification. The onForegroundEvent is not listening to that action, and I'm unable to receive the notification payload or any event type, rather it gives the warning that the onBackgroundEvent is not setup.

The strange thing is that, when the notification is delivered. I'm able to get a log from the onForegroundEvent, for the Event type delivered, but on clicking the notification, nothing happens.

Info

"@notifee/react-native": "^7.2.0",
"react-native": "0.70.5",
"react": "18.2.0",

buildToolsVersion = "31.0.0"
minSdkVersion = 21
compileSdkVersion = 33
targetSdkVersion = 33
kotlinVersion = '1.7.10'

The current workaround, that I'm using is, which was suggested by @mikehardy .

Being, we store the notification in the onBackgroundEvent, in a global state management storage and then retrieve it, wherever in the app we require.

@quicksilverr
Copy link
Author

@helenaford As requested by you, created this issue

@qroac
Copy link

qroac commented Dec 20, 2022

Thanks for posting this.
Yesterday I started to migrate our expo project from expo-notifications to notifee.
I really love the notifications with notifee but I am facing the very same problem.

What I did:

  • added notifee to the project
  • added expo plugin to config, executed expo prebuild and built an expo dev-client that includes notifee
  • added event listeners for foreground, background and initialNotificaton as described in documentation in the main component just before calling registerRootComponent
  • display a dummy notification from somewhere in my code and add a dummy trigger notification as well

What I get:

  • event 7 when trigger notification is scheduled
  • event 3 when one of the notifications is displayed
  • event 0 when user dismisses notification

What I dont get:

  • event 1 after pressing the notification

Opening the app if not in foreground works, I just dont get notified about the event.

"@notifee/react-native@npm:^7.3.0":
  version: 7.3.0
  resolution: "@notifee/react-native@npm:7.3.0"
"react-native@npm:0.69.6":
  version: 0.69.6
  resolution: "react-native@npm:0.69.6"
"expo@npm:^46.0.0, expo@npm:~46.0.17":
  version: 46.0.17
  resolution: "expo@npm:46.0.17"

expo config

plugins: [
      [
        'expo-build-properties',
        {
          android: {
            compileSdkVersion: 33,
            buildToolsVersion: '33.0.0',
          },
        },
      ],
      '@notifee/react-native',
      'sentry-expo',
    ],
   android: {
      package: ...,
      permissions: ['SCHEDULE_EXACT_ALARM'],
      useNextNotificationsApi: true,
      versionCode: 37,
    },

@quicksilverr
Copy link
Author

Hey @qroac, while this is getting fixed, I've just done a temporary workaround.

Assuming that, you are using redux-toolkit and react navigation.

Here are the steps, that I took..

  • First, setup the onBackgroundEvent listener, in your index.js file and dispatch the notification data in it.
  • Then, retrieve it in the component, where you want to do some UI changes.

Here are the code snippets

import { AppRegistry } from 'react-native';
import App from './app/App';
import 'react-native-gesture-handler';
import 'react-native-get-random-values';
import messaging from '@react-native-firebase/messaging';
import notifee from '@notifee/react-native';
import _ from 'lodash';
import { displayNotifications } from 'just_a_wrapper_file';
import { dispatch, storeNotification } from 'your_store';

messaging().setBackgroundMessageHandler(displayNotifications);

notifee.onBackgroundEvent(async ({ type, detail }) => {
  const { notification, pressAction } = detail;
  dispatch(
    storeNotification({
      notification: notification,
      eventType: type,
    })
  );
});

AppRegistry.registerComponent('App', () => App);


imports...

const notificationData = useAppSelector(getNotificationData);

React.useEffect(() => {
    if (navigationRef.isReady()) {
      if (!_.isUndefined(notificationData.notification)) {
        onNotificationEvent(
          notificationData?.notification?.data,
          notificationData.eventType
        );
      }
    }
  }, [notificationData]);

  return (
    <NavigationContainer
      ref={navigationRef}
      fallback={<Text>Loading ...</Text>}
      onReady={() => {
        RNBootSplash.hide({ fade: true });
      }}
    >
<Routes/>
</NavigationContainer>

@AnisDerbel
Copy link

I'm also facing the same problem, onForegroundEvent not getting fired when pressing on the notification on Android

@patissier-boulanger
Copy link

patissier-boulanger commented Jan 6, 2023

Me too. Having same problem. Can't receive foreground event

I'm also facing the same problem, onForegroundEvent not getting fired when pressing on the notification on Android

@helenaford
Copy link
Member

helenaford commented Jan 9, 2023

can you post a step-by-step of how to recreate this bug? it's not clear to me as you mention both the background and foreground event handlers.
I just tested this myself and received a press_event on API Level 33/Android 13 with the app open, pull down the notification drawer and press it.

This is the payload from our test app:

{
   key: 'Basic',
   notification: {
     id: 'basic',
     title: '<p style="color: #4caf50;"><b>Styled HTMLTitle</span></p></b></p> &#128576;',
     android: {
       channelId: 'high',
       pressAction: {
         id: 'default',
       },
     },
     ios: {},
   },
 },
 
 Edit: press event was received but via background handler. For the foreground handler to be triggered, the notification needs to be in a heads-up notification. 

@helenaford helenaford added the needs-feedback Waiting on response to questions label Jan 9, 2023
@helenaford
Copy link
Member

helenaford commented Jan 9, 2023

ohhh, isn't this the same issue #529? I think I understand now what you are saying the problem is... that you're receiving a background event but you think it should be a foreground event instead 🤔

@izakfilmalter
Copy link

izakfilmalter commented Jan 15, 2023

This is a huge problem for us.

It seems to me that there is not a thorough testing process for releases. I have the following testing process for both iOS and Android which would be good to mirror at some level. I get the desire for automated testing, but every release I run into an issue with FCM + Notifee.

  1. App Quit Test
    1. Quit Open Test
      1. Quit the app.
      2. Trigger test notification.
      3. Tap on notification.
      4. App should open to the screen for the notification.
    2. Background Open Test
      1. Quit the app.
      2. Trigger test notification.
      3. Open the app, and dismiss it. The app must still be open in the background.
      4. Tap on notification.
      5. App should open to the screen for the notification.
    3. Foreground Open Test
      1. Quit the app.
      2. Trigger test notification.
      3. Open the app. The app must still be open in the foreground.
      4. Tap on notification.
      5. App should open to the screen for the notification.
  2. App Background Test
    1. Quit Open Test
      1. Open the app, and dismiss it. The app must still be open in the background.
      2. Trigger test notification.
      3. Quit the app after the notification has displayed.
      4. Tap on notification.
      5. App should open to the screen for the notification.
    2. Background Open Test
      1. Open the app, and dismiss it. The app must still be open in the background.
      2. Trigger test notification.
      3. Tap on notification.
      4. App should open to the screen for the notification.
    3. Foreground Open Test
      1. Open the app, and dismiss it. The app must still be open in the background.
      2. Trigger test notification.
      3. Quit the app after the notification has displayed.
      4. Open the app. The app must still be open in the foreground.
      5. Tap on notification.
      6. App should open to the screen for the notification.
  3. App Foreground Test
    1. Quit Open Test
      1. Open the app. The app must still be open in the foreground.
      2. Trigger test notification.
      3. Quit the app after the notification has displayed.
      4. Tap on notification.
      5. App should open to the screen for the notification.
    2. Background Open Test
      1. Open the app. The app must still be open in the foreground.
      2. Trigger test notification.
      3. Dismiss the app. The app must still be open in the background.
      4. Tap on notification.
      5. App should open to the screen for the notification.
    3. Foreground Open Test
      1. Open the app. The app must still be open in the foreground.
      2. Trigger test notification.
      3. Quit the app after the notification has displayed.
      4. Open the app. The app must still be open in the foreground.
      5. Tap on notification.
      6. App should open to the screen for the notification.

@github-actions
Copy link

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

@Ahmedhamed77
Copy link

Hey @qroac, while this is getting fixed, I've just done a temporary workaround.

Assuming that, you are using redux-toolkit and react navigation.

Here are the steps, that I took..

  • First, setup the onBackgroundEvent listener, in your index.js file and dispatch the notification data in it.
  • Then, retrieve it in the component, where you want to do some UI changes.

Here are the code snippets

import { AppRegistry } from 'react-native';
import App from './app/App';
import 'react-native-gesture-handler';
import 'react-native-get-random-values';
import messaging from '@react-native-firebase/messaging';
import notifee from '@notifee/react-native';
import _ from 'lodash';
import { displayNotifications } from 'just_a_wrapper_file';
import { dispatch, storeNotification } from 'your_store';

messaging().setBackgroundMessageHandler(displayNotifications);

notifee.onBackgroundEvent(async ({ type, detail }) => {
  const { notification, pressAction } = detail;
  dispatch(
    storeNotification({
      notification: notification,
      eventType: type,
    })
  );
});

AppRegistry.registerComponent('App', () => App);

imports...

const notificationData = useAppSelector(getNotificationData);

React.useEffect(() => {
    if (navigationRef.isReady()) {
      if (!_.isUndefined(notificationData.notification)) {
        onNotificationEvent(
          notificationData?.notification?.data,
          notificationData.eventType
        );
      }
    }
  }, [notificationData]);

  return (
    <NavigationContainer
      ref={navigationRef}
      fallback={<Text>Loading ...</Text>}
      onReady={() => {
        RNBootSplash.hide({ fade: true });
      }}
    >
<Routes/>
</NavigationContainer>

if you use messaging().setBackgroundMessageHandler(displayNotifications); this wouldn't duplicate notifications for you on android ? if so how did you solve it ?
because whenever I use messaging().setBackgroundMessageHandler(displayNotifications); I get two notifications
one from FCM and the other is from notifee
how did you manage to get one notification from notifee only ?

@artus9033
Copy link

The issue is still present in 7.4.0

@lmalvasia
Copy link

notificationData

Still having this issue in 7.5.0

I could make a workaround using redux and redux persist, following the example posted by quicksilverr. Thanks

@criss02-cs
Copy link

still having this issue, i can listen DELIVERED event, but when i press the notification it does nothing

@joel611
Copy link

joel611 commented Mar 10, 2023

Having the same problem, only receive delivered events onForegroundEvent but no press events.

@k0502s
Copy link

k0502s commented Mar 20, 2023

I also checked that it was not working. Event 1 is not displayed after clicking Alert. on Android

@fgagneten
Copy link

fgagneten commented Mar 20, 2023

Same issue here! Android 12. Only "delivered" event works. Issue still present in 7.6.1

@helenaford
Copy link
Member

does anyone know when this stopped working? I'm looking into this now, can see the issue you describe. definitely hasn't always been like this.

i wonder if it's todo with android 12 +.

@izakfilmalter
Copy link

It's been an issue for at least the last 5 months. Didn't seem to be an issue in October last year but by December I've been fighting it.

@k0502s
Copy link

k0502s commented Mar 22, 2023

@helenaford

In my case, there was a problem with Android 12 version.

@helenaford
Copy link
Member

helenaford commented Mar 23, 2023

Hey All, I've pushed a solution and a pre-release of v7.7.0-0.

npm i @notifee/[email protected]

I've left some notes on the p/r with a screen recording showing the final result. #720

I will not actually publish this as a final version until Monday which gives time for feedback.

Reopened issue for now until it's in a final release.

@helenaford helenaford reopened this Mar 23, 2023
@Sandeep145XamRN
Copy link

Hey @helenaford I am currently facing with triggering the onPress event of notification click when a notification is received in the background.

As when a notification is received in the foreground, the onPress event is triggered without any issues. However, when the notification is received in the background, the onPress event is not triggered (notifee.onBackgroundEvent).
with version v7.7.0-0.

I have added my index.js class code

/**
 * @format
 */

import { AppRegistry } from 'react-native'
import AppCover from './src/App'
import { name as appName } from './app.json'
import { startNetworkLogging } from 'react-native-network-logger';
import notifee, { EventType } from '@notifee/react-native';
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';


notifee.onBackgroundEvent(async ({ type, detail }) => {
    console.warn('notification background handler',type,detail)
    const { notification, pressAction } = detail;
    // Check if the user pressed 
    if (type === EventType.ACTION_PRESS) {
        console.warn('notification read')
        // Remove the notification
        await notifee.cancelNotification(notification.id);
    }
});

AppRegistry.registerComponent(appName, () => gestureHandlerRootHOC(AppCover))

@k0502s
Copy link

k0502s commented Mar 31, 2023

me too. @Sandeep145XamRN

"react-native": "0.66.3", "@notifee/react-native": "7.7.0-0"

I tested it with v7.7.0-0.
For the foreground, Press event started working well, but now Press event doesn't seem to work in the background.

The devices tested are Galaxy s20 and Android 12 versions.

@helenaford Thank you for your efforts to solve this problem.

@MandeepKaur-1
Copy link

I'm facing the same issue @Sandeep145XamRN @k0502s have you found any solution?

"react-native": "0.70.6", "@notifee/react-native": "7.7.0-0"

@helenaford thanks for a great library. I understand that you are dealing with a lot of issues, but I wanted to bring your attention to a particular issue, which is crucial, I'm unable to work on notification re-direction. Any guidance will be appreciated.

@ucheNkadiCode
Copy link

When using remote notifications on React Native, I've had the most luck with these docs. It directly states that onForegroundEvent will fire when it's a remote notification.

I'm able to send notifications via the Firebase Messaging Console. The way I've handled it is to place the notifee.onForegroundEvent subscriber onto my home screen and then handle any navigation logic from there. That way I have access to a navigation object and can navigate or pass params. Surprisingly, this onForegroundEvent code even runs from the kill state. I am only able to get onBackgroundEvent to fire from local notifications while the app is running, not remote notifications

Using
"@notifee/react-native": "^7.7.1",
"react-native": "^0.72.4",
"@react-native-firebase/app": "^14.12.0",
"@react-native-firebase/messaging": "^14.12.0",

// One Time USE EFFECT function to set things up!!
  useEffect(() => {
    const unsubscribeNotifee = notifee.onForegroundEvent(
      async ({ type, detail }) => {
        console.log(
          `The type is`,
          type,
          "the detail is",
          detail
        );
        switch (type) {
          case EventType.PRESS:
            if (detail.notification?.remote) {
               console.log("It was a remote notification")
              // Do some navigation logic
            }
            break;
          case EventType.ACTION_PRESS:
            console.log(`It was an ACTION PRESS THO`)
            break;
        }
      }
    );
    return () => {
      unsubscribeNotifee();
    };
  }, []);

@Eclipses-Saros
Copy link

Eclipses-Saros commented Sep 11, 2024

If you're using RN >= 0.73 (Bridgeless Enabled) latest notifee and above Android 12, onForegroundEvent and onBackgroundEvent event are not working.

I think I found a way. the main reason notifee event not working is, ReactContext is null. due to new architecture system, getting react context dynamically is not working as expected.

NotifeeReactUtils.java

private static @Nullable ReactContext getReactContext() {
  ReactNativeHost reactNativeHost =
    ((ReactApplication) EventSubscriber.getContext()).getReactNativeHost();
  ReactInstanceManager reactInstanceManager = reactNativeHost.getReactInstanceManager();
  return reactInstanceManager.getCurrentReactContext(); // <- returns null
}

since mCurrentReactContext is null, sendEvent can't do the job, just end function to prevent further error.

static void sendEvent(WritableMap eventMap) {
  try {
    ReactContext reactContext = getReactContext();

    if (reactContext == null || !reactContext.hasActiveCatalystInstance()) {
      return;
    }

    reactContext
      .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
      .emit(NotifeeEventSubscriber.NOTIFICATION_EVENT_KEY, eventMap);

  } catch (Exception e) {
    Log.e("SEND_EVENT", "", e);
  }
}

fortunately, there is a dirty & quick fix. after reading RN docs (https://reactnative.dev/docs/native-modules-android#sending-events-to-javascript), something came to my mind. notifee initializes modules with NotifeeApiModule, you can get reactApplicationContext from NotifeeApiModule.

NotifeeApiModule.java

public class NotifeeApiModule extends ReactContextBaseJavaModule implements PermissionListener {
  private static final int NOTIFICATION_TYPE_DISPLAYED = 1;
  private static final int NOTIFICATION_TYPE_TRIGGER = 2;
  private static final int NOTIFICATION_TYPE_ALL = 0;
  private static ReactApplicationContext context; // <- add this line

  public NotifeeApiModule(@NonNull ReactApplicationContext reactContext) {
    super(reactContext);
    context = reactContext; // <- add this line
  }
  
  // add this function to access react context anywhere
  public static ReactApplicationContext getContext() {
    return context;
  }

and edit getReactContext function... you're good to go.

private static @Nullable ReactContext getReactContext() {
//  ReactNativeHost reactNativeHost =
//    ((ReactApplication) EventSubscriber.getContext()).getReactNativeHost();
//  ReactInstanceManager reactInstanceManager = reactNativeHost.getReactInstanceManager();
//  return reactInstanceManager.getCurrentReactContext();
  return NotifeeApiModule.getContext(); // <- add this line and import
}
image

yes. works well. no more problem with onForegroundEvent and onBackgroundEvent.

but this fix cause another problem: If you press notification from background, bundle loads again and cause weird error.

Error: Exception in HostFunction: Could not enqueue microtask because they are disabled in this runtime, js engine: hermes

Error: Failed to call into JavaScript module method AppRegistry.startHeadlessTask(). Module has not been registered as callable. Registered callable JavaScript modules (n = 10): RNCWebViewMessagingModule, GlobalPerformanceLogger, RCTNativeAppEventEmitter, RCTEventEmitter, SamplingProfiler, RCTDeviceEventEmitter, HMRClient, RCTLog, HeapCapture, Systrace. Did you forget to call registerCallableModule?

++ If you're not interested in fixing ApiModule, there is other way to do it. but this one won't fix onBackgroundEvent.

private static @Nullable ReactContext getReactContext() {
  if (DefaultNewArchitectureEntryPoint.getBridgelessEnabled()) {
    ReactHost reactHost =
      ((ReactApplication) EventSubscriber.getContext()).getReactHost();
    return reactHost.getCurrentReactContext();
  } else {
    ReactNativeHost reactNativeHost =
      ((ReactApplication) EventSubscriber.getContext()).getReactNativeHost();
    ReactInstanceManager reactInstanceManager = reactNativeHost.getReactInstanceManager();
    return reactInstanceManager.getCurrentReactContext();
  }
}

@Eclipses-Saros
Copy link

After many research, Error: Failed to call into JavaScript module method AppRegistry.startHeadlessTask(). Module has not been registered as callable. error was HeadlessJsTask problem. you can't run background task from foreground. however, at this point, I feel something is WRONG.

pressing notification from background -> opens App -> isAppInForeground() returns false -> run HeadLessJsTask -> error!

what's going on here? pressing notification will make app pops up (bringing app status background to foreground), so it should be foreground event. (well still, background event is okay to me. if it's working correctly)

this is confusing. even if app is background, it's still alive, should be return 'RESUMED' event... but It's not. maybe react context lifecycle detects status better than ProcessLifecycleOwner? let me check...

static boolean isAppInForeground() {
    Log.d("Notifee - ProcessLifecycleOwner", ProcessLifecycleOwner.get().getLifecycle().getCurrentState().toString());
    Log.d("Notifee - ReactContext Lifecycle", NotifeeApiModule.getContext().getLifecycleState().toString());
    
    return ProcessLifecycleOwner.get()
        .getLifecycle()
        .getCurrentState()
        .isAtLeast(Lifecycle.State.RESUMED);
  }

androidx.lifecycle has 5 status: CREATED, RESUMED, DESTROYED, STARTED, INITIALIZED.
com.facebook.react.common.LifecycleStatus has 3 status: RESUMED, BEFORE_CREATE, BEFORE_RESUMED.

Android Lifecycle (https://developer.android.com/guide/components/activities/activity-lifecycle) follows these steps: onCreate -> onStart -> onResume -> (App Running) -> onPause -> onStop -> onDestroy.
if user brings other app in foreground, it will fall into pause status (onPause). once user brings back to foreground my app, app is resumed (onResume).

so let's do some test: receive notification from foreground, and press home button to make app background, press notification. if the theory correct, app will shows up and logcat will print RESUMED text.

image

but NO. CREATED was called.
first receive event is resumed, which is correct. but second press event is created.

I mean, HOW?
did I miss something? was android intent works differently?

@Eclipses-Saros
Copy link

I can't figure out why. :/ anyone who're good at Android. please dig this issue more.
but for now, I'll leave patch file if you want to fix this problem. use at your own risk. it's not fully-tested.

@notifee+react-native+9.0.0.patch

NotifeeApiModule.java

public class NotifeeApiModule extends ReactContextBaseJavaModule implements PermissionListener {
private static final int NOTIFICATION_TYPE_DISPLAYED = 1;
private static final int NOTIFICATION_TYPE_TRIGGER = 2;
private static final int NOTIFICATION_TYPE_ALL = 0;
private static ReactApplicationContext context; // <- add static variable to hold ReactApplicationContext.

public NotifeeApiModule(@NonNull ReactApplicationContext reactContext) {
  super(reactContext);
  context = reactContext; // <- add this line
}

// make this method to get context elsewhere
public static ReactApplicationContext getContext() {
  return context;
}

NotifeeReactUtils.java

private static @Nullable ReactContext getReactContext() {
  //  ReactNativeHost reactNativeHost =
  //      ((ReactApplication) EventSubscriber.getContext()).getReactNativeHost();
  //  ReactInstanceManager reactInstanceManager = reactNativeHost.getReactInstanceManager();
  //  return reactInstanceManager.getCurrentReactContext();
  return NotifeeApiModule.getContext(); // <- add this line. don't worry, ReactApplicationContext can be converted into ReactContext
}

static boolean isAppInForeground() {
  return ProcessLifecycleOwner.get()
      .getLifecycle()
      .getCurrentState()
      .isAtLeast(Lifecycle.State.CREATED); // <- change RESUME to CREATED.
}

@Eclipses-Saros
Copy link

@helenaford can we open this again? this issue was not fixed and still persists.

@mikehardy mikehardy reopened this Sep 15, 2024
@pierroo
Copy link

pierroo commented Sep 20, 2024

I'm on
notifee 9.0.2
RN 0.73.5
targetsdk 34

using FCM (if that matters) I can confirm only the "DELIVERED" event is detected by notifee.onBackgroundEvent
even the notifee.onForegroundEvent isn't detected
and the notifee.getInitialNotification();

(I guess they are all related)

on the other hand, the "messaging().setBackgroundMessageHandler" from FCM does detect the notification in background;
which btw triggers the double display of notification if you use "await notifee.displayNotification" inside it (issue mentioned a while ago in this thread)

and the FCM messaging().onMessage also works on foreground

@abdulragib

This comment was marked as resolved.

@abdulragib

This comment was marked as resolved.

@Eclipses-Saros

This comment was marked as resolved.

@abdulragib

This comment was marked as resolved.

@Eclipses-Saros
Copy link

okay, I found a... very sad solution. disabling bridgeless mode definitely fixes all problems.

override fun onCreate() {
    super.onCreate()
    SoLoader.init(this, false)
    load(bridgelessEnabled=false) // <- add this in function parameters
}

however this one, realllllly bad solution. after RN 0.73, bridgeless mode is enabled by default and they're ready to completely replace old one. soon or not, we cannot keep the old way.

and even more worse thing. contributor of RN said "most likely deprecate and remove Headless JS in a future version". basically bridgeless mode disables any asynchronous action (aka micro task), including HEADLESS TASK. since firebase messaging also depends on this one, it... might be getting into really bad situation.

@mikehardy
Copy link
Collaborator

Indeed - getting Notifee working well with new architecture (and RNFB as needed) is something I'm paying attention to
The time is getting close as well, I'm well aware of that

@Eclipses-Saros
Copy link

after investigating more same issue, I can summarize this problem:

  1. enabling Bridgeless mode makes getting ReactContext from ReactNativeHost null.
    yes. you cannot get context from ReactNativeHost. you need to change getReactNativeHost() to getReactHost(), or getting context directly from module.
private static @Nullable ReactContext getReactContext() {
  if (DefaultNewArchitectureEntryPoint.getBridgelessEnabled()) {
    ReactHost reactHost =
      ((ReactApplication) EventSubscriber.getContext()).getReactHost();
    return reactHost.getCurrentReactContext();
  } else {
    ReactNativeHost reactNativeHost =
      ((ReactApplication) EventSubscriber.getContext()).getReactNativeHost();
    ReactInstanceManager reactInstanceManager = reactNativeHost.getReactInstanceManager();
    return reactInstanceManager.getCurrentReactContext();
  }
}
  1. also it makes HeadlessJsTaskService broken.

Error: Exception in HostFunction: Could not enqueue microtask because they are disabled in this runtime, js engine: hermes

Error: Failed to call into JavaScript module method AppRegistry.startHeadlessTask(). Module has not been registered as callable. Registered callable JavaScript modules (n = 10): RNCWebViewMessagingModule, GlobalPerformanceLogger, RCTNativeAppEventEmitter, RCTEventEmitter, SamplingProfiler, RCTDeviceEventEmitter, HMRClient, RCTLog, HeapCapture, Systrace. Did you forget to call registerCallableModule?

first error is bridgeless problem. you cannot do any asynchronous js job since architecture blocks it. this cause everything wrong. - once error occurs, background event will be dead and not listening further messages.

second error is AppRegistry was not treated as a Callable Module in bridgeless mode, (also pressing notification will make app status CREATED, not resumed.) so background event will eventually failed.

you can find workaround here, if you're interested.

@mikehardy
Copy link
Collaborator

@Eclipses-Saros your investigation and testing here, and all of the findings you posted is incredibly valuable, thank you

@mikehardy
Copy link
Collaborator

mikehardy commented Oct 18, 2024

I have released a fix that should be backwards compatible to older react-native versions (I tested down to 0.72) in #1127 as v9.1.2 here

Please understand that there is a gigantic mix of issues above, and to my knowledge:

  • there were 2 real ones that are both now solved (android 12+ has lifecycle issues solved long ago, react-native new architecture has reactContext issues solved just now)
  • there are lots of people setting up listeners with expectations contrary to the way the package works

Now I understand that the way the package works is a little subtle and a little irritating in a few ways right now but that's not a reason to keep this issue open - we're working on addressing that elsewhere


If there are further problems with getting the events to register at all please open a new issue with a reproducible example


Thanks!

@mikehardy mikehardy removed the needs-feedback Waiting on response to questions label Oct 20, 2024
@invertase invertase locked as resolved and limited conversation to collaborators Oct 20, 2024
@mikehardy mikehardy unpinned this issue Oct 20, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet