Skip to content

[🐛] messaging on iOS on new architecture needs updated docs / implementation to handle isHeadless / quit state #8217

Open

Description

@aliceni81

Hi, I'm using react native v0.76.5 (new architecture is enabled) and react-native-firebase/messaging v21.6.2.

According to the documentation, I have the following code in index.js

messaging().setBackgroundMessageHandler(async remoteMessage => {
  //
});

const HeadlessCheck = ({ isHeadless }) => {
  if (isHeadless) return null;
  return <App />;
}

AppRegistry.registerComponent(appName, () => HeadlessCheck);

I have the the following code in AppDelegate.mm:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.moduleName = @"gk_research_app_staging";
  // You can add your custom initial props in the dictionary below.
  // They will be passed down to the ViewController used by React Native.
  // self.initialProps = @{};

  // return [super application:application didFinishLaunchingWithOptions:launchOptions];
  self.initialProps = [RNFBMessagingModule addCustomPropsToUserProps:nil withLaunchOptions:launchOptions];
  [FIRApp configure];
  [application registerForRemoteNotifications];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

I have a problem for iOS device - when the app is in quit state and receives a notification, after a few seconds, I click the notification which makes the app open, but nothing is shown. I know it's because of "if (isHeadless) return null;".

The following logs are in my console:
When the app is opened(foreground/background):
Running "test_app" with {"rootTag":1,"initialProps":{"concurrentRoot":true,"isHeadless":false},"fabric":true}
When the app is quit and receives a notification, the bundle is re-generated:
Running "test_app" with {"rootTag":1,"initialProps":{"concurrentRoot":true,"isHeadless":true},"fabric":true}
When re-open the app or open the app by the notification, the bundle is not regenerated and keep the last state:
Running "test_app" with {"rootTag":1,"initialProps":{"concurrentRoot":true,"isHeadless":true},"fabric":true}

This issue does not happen when the app is already open, no matter if it is in foreground or background state, because the bundle will not be re-generated.

To make the app UI display, I need to exit the app and open the app again which cause the bundle re-generated:
Running "test_app" with {"rootTag":1,"initialProps":{"concurrentRoot":true,"isHeadless":false},"fabric":true}

How can I solve this issue?
I need your help!!!

Related:
#5388

I've submitted a bug report in react native:
react/react-native#48551

Activity

  1. changed the title [-][🐛] Bug Report Title - CHANGE ME [/-] [+][🐛] Bug Report - App displays nothing if receives a notification in quit state[/+] on Jan 8, 2025
  2. aliceni81 commented on Jan 9, 2025

    @aliceni81
    Author

    @mikehardy Can you please help? Much appreciated!

  3. changed the title [-][🐛] Bug Report - App displays nothing if receives a notification in quit state[/-] [+][🐛] Bug Report [react-native-firebase/messaging] - App displays nothing if receives a notification in quit state[/+] on Jan 11, 2025
  4. changed the title [-][🐛] Bug Report [react-native-firebase/messaging] - App displays nothing if receives a notification in quit state[/-] [+][🐛] Bug Report [react-native-firebase/messaging] - App displays nothing if receives a notification in quit state for iOS[/+] on Jan 11, 2025
  5. github-actions commented on Feb 24, 2025

    @github-actions
    Contributor

    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.

  6. bean2307 commented on May 15, 2025

    @bean2307

    +1 same issue

  7. tux2nicolae commented on Sep 14, 2025

    @tux2nicolae

    I do have the same issue on new architecture, can you consider reopening this issue?

  8. aliceni81 commented on Sep 16, 2025

    @aliceni81
    Author

    I do have the same issue on new architecture, can you consider reopening this issue?

    Please refer to #8248 (comment)

  9. tux2nicolae commented on Sep 16, 2025

    @tux2nicolae

    @aliceni81 thank you.

    Indeed it worked for us with a similar workaround, only from our tests it seems we also need to run a useEffect for the initial value, it seems there are some cases when shouldRenderUI will still be wrongly false without it.

    function HeadlessCheck({ isHeadless }) {
      const [shouldRenderUI, setShouldRenderUI] = useState(!isHeadless);
    
      // Workaround for iOS not providing the headless parameter
      // https://github.com/invertase/react-native-firebase/issues/8248#issuecomment-2686603423
      const headlessCheck = useCallback(async () => {
        if (Platform.OS === 'ios') {
          const isHeadlessValue = await getIsHeadless(getMessaging());
          setShouldRenderUI(!isHeadlessValue);
        }
      }, []);
    
      React.useEffect(() => {
        headlessCheck();
      }, []);
    
      useOnAppChange(headlessCheck);
    
      return shouldRenderUI ? <App /> : null;
    }

    But this may seem to be more of a workaround to the problem instead of a proper solution, since basically isHeadless is unused at all, the best fix for this I see is that the isHeadless be correctly set from the native side but don't know what implications there are to do that.

  10. mikehardy commented on Jan 29, 2026

    @mikehardy
    Collaborator

    @tux2nicolae sorry for resurrecting this old issue, but I'm scanning things that went stale without response.

    I notice in your workaround useOnAppChange and getIsHeadless are methods not defined in the code you posted. What is the definition for those methods? This could form the basis of a complete solution for new architecture

  11. tux2nicolae commented on Jan 29, 2026

    @tux2nicolae

    Hi @mikehardy,

    Sure, the useOnAppChange() hook is an internal hook that actually should be called more like useOnActiveAppState but for historical we did not renamed it yet.

    import {useEffect, useRef} from 'react';
    import {AppState} from 'react-native';
    
    const useOnAppChange = (callback: (...args: any[]) => any) => {
      const appState = useRef(AppState.currentState);
    
      useEffect(() => {
        const subscription = AppState.addEventListener('change', nextAppState => {
          if (
            appState.current.match(/inactive|background/) &&
            nextAppState === 'active'
          ) {
            callback();
          }
          appState.current = nextAppState;
        });
        return () => {
          subscription.remove();
        };
      }, [callback]);
    };
    
    export default useOnAppChange;

    The getIsHeadless it's actually from the library itself

    import { getIsHeadless, getMessaging } from '@react-native-firebase/messaging';
  12. changed the title [-][🐛] Bug Report [react-native-firebase/messaging] - App displays nothing if receives a notification in quit state for iOS[/-] [+][🐛] messaging on iOS on new architecture needs updated docs / implementation to handle isHeadless / quit state[/+] on Jan 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions