Repository navigation
馃敟 [馃悰] isHeadless flag on iOS unreliable聽#5388
Description
The issue is that the isHeadless flag included in @react-native-firebase/messaging is unreliable and causes the app to render null when the app is opened. The flag can be true initially when the app is launching but does not update to false when the app is in the foreground.
Please see this code snippet which is taken from the docs:
// index.js
import { AppRegistry } from 'react-native';
import messaging from '@react-native-firebase/messaging';
messaging().setBackgroundMessageHandler(async remoteMessage => {
console.log('Message handled in the background!', remoteMessage);
});
function HeadlessCheck({ isHeadless }) {
if (isHeadless) {
// App has been launched in the background by iOS, ignore
return null;
}
return <App />;
}
function App() {
// Your application
}
AppRegistry.registerComponent('app', () => HeadlessCheck);
There have been previous discussions around the usage of this flag:
#4163
#4304
Some suggestions to listen to AppState rather than use the isHeadless flag but it's unclear what the best solution is to prevent the app from rendering when it's in a headless state.
From reading the discussions, it's clear the isHeadless flag causes unpredictable results, is there anything that can be done in the library to fix the flag?
Or, can the docs be updated to show a recommended solution?
Project Files
Javascript
Click To Expand
package.json:
# N/Afirebase.json for react-native-firebase v6:
# N/AiOS
Click To Expand
ios/Podfile:
- I'm not using Pods
- I'm using Pods and my Podfile looks like:
# N/AAppDelegate.m:
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
if ([FIRApp defaultApp] == nil) {
[FIRApp configure];
}
...
NSDictionary *appProperties = [RNFBMessagingModule addCustomPropsToUserProps:nil withLaunchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"xxx"
initialProperties:appProperties];
...
[RNBootSplash initWithStoryboard:@"BootSplash" rootView:rootView];
return YES;
}Android
Click To Expand
Have you converted to AndroidX?
- my application is an AndroidX application?
- I am using
android/gradle.settingsjetifier=truefor Android compatibility? - I am using the NPM package
jetifierfor react-native compatibility?
android/build.gradle:
// N/Aandroid/app/build.gradle:
// N/Aandroid/settings.gradle:
// N/AMainApplication.java:
// N/AAndroidManifest.xml:
<!-- N/A -->Environment
Click To Expand
react-native info output:
OUTPUT GOES HERE
- Platform that you're experiencing the issue on:
- [ x] iOS
- Android
- iOS but have not tested behavior on Android
- Android but have not tested behavior on iOS
- Both
react-native-firebaseversion you're using that has this issue:e.g. 5.4.3
Firebasemodule(s) you're using that has the issue:e.g. Instance IDMessaging
- Are you using
TypeScript?Y/N&VERSIONY
- 馃憠 Check out
React Native FirebaseandInvertaseon Twitter for updates on the library.
Activity
miallo commentedon Jul 7, 2021
Is there a place where I can look into this thing and see if I can find the problem? This bug is causing us quite some troubles...
mikehardy commentedon Jul 7, 2021
This is an area of some pain that I've looked into a bit yes. We use detox as our testing solution in the e2e app and unfortunately it does not allow for running on-device on iOS devices, so near as I can tell there is no way to make an automated test for it.
So I think the best path is actually to carefully (that is, take care not to npm/yarn install as it will potentially blow away your changes) reach right into node_modules and then roll up the sleeves and get dirty with the .m and .js files directly in the messaging module
It appears based on my understanding of the problem that there are a couple of things:
This may actually fail if used on android? There is no android implementation - but this is a tangent:
react-native-firebase/packages/messaging/lib/index.js
Lines 128 to 130 in 5039759
This implementation which is checking for foreground or background:
react-native-firebase/packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m
Lines 53 to 55 in 5039759
Is probably best not as a property that is accessed but as something that is determined each time here:
react-native-firebase/packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m
Lines 149 to 156 in 5039759
Then it would accurately reflect whether the app is in the background or not?
mikehardy commentedon Jul 7, 2021
(hit enter too soon, updated comment above - https://github.com/ds300/patch-package may be used to test your changes more reliably, and then the same work can be proposed as a PR here?)
miallo commentedon Jul 8, 2021
A bit of debugging later...
Here we successfully register the listener for getting into foreground
react-native-firebase/packages/messaging/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m
Line 52 in c94546d
The docs say that the selector function
but even if we add that, it does not change that this function is never called
react-native-firebase/packages/messaging/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m
Line 133 in c94546d
So here we never set the
isHeadlessto falsereact-native-firebase/packages/messaging/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m
Line 147 in c94546d
The default YES value is also never called and the only reference we could find for the
addCustomPropsToUserPropsfunction is in the respective .h file.react-native-firebase/packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m
Line 48 in d97587b
I have to say my knowledge about how RN works is even less than how ObjC is working but maybe this is a first hint?
miallo commentedon Jul 8, 2021
Right... If I only followed the instructions to update the AppDelegate.m I would have called the
addCustomPropsToUserPropsmyself... Sorry for my stupidity...ease-space commentedon Sep 18, 2021
This code fixed bug

mym0404 commentedon Feb 17, 2022
if i send message with
content-availablein quit state,isHeadlessis true during next app open timestale commentedon Apr 16, 2022
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 the community's attention?
stale commentedon May 1, 2022
Closing this issue after a prolonged period of inactivity. If this is still present in the latest release, please feel free to create a new issue with up-to-date information.
orange-brother commentedon Dec 13, 2022
Same here. If i remove content-available in json, isHeadless works fine.
yuvraj-scalex commentedon Apr 4, 2023
This issue is surfacing in our production app and redirects users to the blank screen as isHeadless is true when the app is launched from the quit state. Even though we return
<App />component when isHeadless is true, it is completely messing up with the navigation of the App.Is there any way we can fix this?
RN version: 0.68.5
react-native-firebase: 17.4.1
react: 17.0.2
yuvraj-scalex commentedon Apr 14, 2023
Hello @mikehardy, can you pl suggest something to get rid of this issue?
We've upgraded the react-native-firebase packages but still have no luck with this issue, should we upgrade the react-native version as well?
github-actions commentedon May 12, 2023
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?
Thank you for your contributions.
miladdev85 commentedon May 31, 2023
Is there any progress here? This issue should not be closed.
isHeadless does not change or get updated.
Alex1899 commentedon Jun 13, 2023
I am experiencing the same issue. When the app opens from pressing the background notification, isHeadless stays true
humaidk2 commentedon Nov 29, 2023
Hi,
I spent some time investigating this issue and found the solution.
The problem comes from updating app properties while the bridge has not been loaded.
It's an issue that comes from react native, react/react-native#20115
but react-native suggested that they won't be solving it,
There's 2 suggested solutions:
1 is to wait for js to load then set the props, but this didn't work for us
2 is to patch react native, which did work for us
https://github.com/facebook/react-native/pull/20116/files
mikehardy commentedon Nov 29, 2023
@humaidk2 react-native-firebase definitely has some things that only load after the javascript environment comes up and to my knowledge it has been working reliably. Patching react-native in those files implies a local fork / build of react-native is very painful from a maintenance perspective making a javascript observer a strong preference
This notification is used internally in react-native I'm surprised it's not working, they appear to be specifying the bridge as the object to observe though, I wonder if you follow their addObserver pattern it might work better? Examples:
https://github.com/search?q=repo%3Afacebook%2Freact-native+RCTJavaScriptDidLoadNotification&type=code