You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When on android everything works as intended while, on iOS, i receive the notification while the app is in Background or quit but the onMessage or backgroundMessageHandler methods never trigger. I added Background fetch, Remote notifications and Push notifications from Signing Capabilities in Xcode. I already set the content-available: true from the server but it doesnt seem to work.
I've already looked through a lot of workaround and solutions but nothing seems to work in my case...
App.tsx:
exportconstNAVIGATION_PERSISTENCE_KEY="NAVIGATION_STATE"constNAVIGATION_IDS=["login","home","notifications"]// Web linking configurationconstprefixes=Linking.createURL("")constconfig={screens: {Onboarding: "onboarding",Login: "login",TargetSetting: "target-setting",Main: {screens: {Home: {screens: {Home: "home",EnvImpact: "env-impact",},},Data: "data",System: "system",Condo: "condo",Sustainability: "sustainability",},},Notifications: "notifications",Profile: "profile",Quiz: "quiz",QuizLanding: "quizlanding",Integrations: "integrations",Welcome: "welcome",Support: "support",Tutorial: "tutorial",DailyConsumptionDetail: "daily-consumption-detail",Demo: {screens: {DemoShowroom: {path: "showroom/:queryIndex?/:itemIndex?",},DemoDebug: "debug",DemoPodcastList: "podcast",DemoCommunity: "community",},},},}interfaceAppProps{hideSplashScreen: ()=>Promise<void>}/** * This is the root component of our app. */functionApp(props: AppProps){const{ hideSplashScreen }=props/* const { initialNavigationState, onNavigationStateChange, isRestored: isNavigationStateRestored, } = useNavigationPersistence(storage, NAVIGATION_PERSISTENCE_KEY) */const[areFontsLoaded]=useFonts(customFontsToLoad)useEffect(()=>{setTimeout(hideSplashScreen,500)},[])// Before we show the app, we have to wait for our state to be ready.// In the meantime, don't render anything. This will be the background// color set in native by rootView's background color.// In iOS: application:didFinishLaunchingWithOptions:// In Android: https://stackoverflow.com/a/45838109/204044// You can replace with your own loading component if you wish.if(!areFontsLoaded)returnnull// function buildDeepLinkFromNotificationData(data): string | null {// if (!data) {// return null// }// console.log(data)// // const navigationId = data?.navigationId// // if (!NAVIGATION_IDS.includes(navigationId)) {// // console.warn("Unverified navigationId", navigationId)// // return null// // }// // if (navigationId === "login") {// // console.log("redirect to login")// // return prefixes + "login"// // }// // if (navigationId === "home") {// // console.log("redirect to home")// // return prefixes + "home"// // }// // if (navigationId === "notifications") {// // console.log("redirect to notifications")// // return prefixes + "notifications"// // }// // console.warn("Missing postId")// // return null// return prefixes + "notifications"// }constlinking={
prefixes,
config,asyncgetInitialURL(){consturl=awaitLinking.getInitialURL()if(typeofurl==="string"){returnurl}// getInitialNotification: When the application is opened from a quit state.// const message = await messaging().getInitialNotification()// const deeplinkURL = buildDeepLinkFromNotificationData(message?.data)// if (typeof deeplinkURL === "string") {// return deeplinkURL// }},subscribe(listener: (url: string)=>void){constonReceiveURL=({ url }: {url: string})=>listener(url)// Listen to incoming links from deep linkingconstlinkingSubscription=Linking.addEventListener("url",onReceiveURL)// const foregroundUnsubscribe = messaging().onMessage((remoteMessage) => {// console.log("FORE",remoteMessage)// //NotificationStorage.setItem("isNewNotification", true)// })// onNotificationOpenedApp: When the application is running, but in the background.constunsubscribe=messaging().onNotificationOpenedApp((remoteMessage)=>{console.log(remoteMessage)navigationRef.navigate("Notifications")// const url = buildDeepLinkFromNotificationData(remoteMessage.data)// if (typeof url === "string") {// listener(url)// }})return()=>{linkingSubscription.remove()unsubscribe()}},}messaging().setBackgroundMessageHandler(asyncmsg=>{console.log("AAAA",msg)NotificationStorage.setItem("isNewNotification",true)})messaging().onMessage(asyncremoteMessage=>{console.log("ON MESSAGE")NotificationStorage.setItem("isNewNotification",true)});// otherwise, we're ready to render the appreturn(<RootSiblingParent><BottomSheetModalProvider><SafeAreaProviderinitialMetrics={initialWindowMetrics}><ErrorBoundarycatchErrors={Config.catchErrors}><ApiProviderapi={apiSlice}><GestureHandlerRootViewstyle={{flex: 1}}><AppNavigatorlinking={linking}/* initialState={initialNavigationState} onStateChange={onNavigationStateChange} *//></GestureHandlerRootView></ApiProvider></ErrorBoundary></SafeAreaProvider></BottomSheetModalProvider></RootSiblingParent>)}exportdefaultApp
Also this is the code used to trigger the notification
requireFile.join(File.dirname(`node --print "require.resolve('expo/package.json')"`),"scripts/autolinking")requireFile.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`),"scripts/react_native_pods")requireFile.join(File.dirname(`node --print "require.resolve('@react-native-community/cli-platform-ios/package.json')"`),"native_modules")use_modular_headers!require'json'podfile_properties=JSON.parse(File.read(File.join(__dir__,'Podfile.properties.json')))rescue{}ENV['RCT_NEW_ARCH_ENABLED']=podfile_properties['newArchEnabled'] == 'true' ? '1' : '0'ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR']='1'ifpodfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR'] == 'true'platform:ios,podfile_properties['ios.deploymentTarget'] || '14.0'install!'cocoapods',:deterministic_uuids=>falseprepare_react_native_project!# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.# because `react-native-flipper` depends on (FlipperKit,...), which will be excluded. To fix this,# you can also exclude `react-native-flipper` in `react-native.config.js`## ```js# module.exports = {# dependencies: {# ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),# }# }# ```flipper_config=FlipperConfiguration.disabledifENV['NO_FLIPPER'] == '1'then# Explicitly disabled through environment variablesflipper_config=FlipperConfiguration.disabledelsifpodfile_properties.key?('ios.flipper')then# Configure Flipper in Podfile.properties.jsonifpodfile_properties['ios.flipper'] == 'true'thenflipper_config=FlipperConfiguration.enabled(["Debug","Release"])elsifpodfile_properties['ios.flipper'] != 'false'thenflipper_config=FlipperConfiguration.enabled(["Debug","Release"],{'Flipper'=>podfile_properties['ios.flipper']})endendtarget'A2AEnergyHub'douse_expo_modules!config=use_native_modules!use_frameworks!:linkage=>podfile_properties['ios.useFrameworks'].to_symifpodfile_properties['ios.useFrameworks']use_frameworks!:linkage=>ENV['USE_FRAMEWORKS'].to_symifENV['USE_FRAMEWORKS']use_frameworks!:linkage=>:static
$RNFirebaseAsStaticFramework =true# Flags change depending on the env values.flags=get_default_flags()pod'react-native-config',:path=>'../node_modules/react-native-config'# For extensions without React dependenciespod'react-native-config/Extension',:path=>'../node_modules/react-native-config'use_react_native!(:path=>config[:reactNativePath],:hermes_enabled=>podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',:fabric_enabled=>flags[:fabric_enabled],# An absolute path to your application root.:app_path=>"#{Pod::Config.instance.installation_root}/..",# Note that if you have use_frameworks! enabled, Flipper will not work if enabled:flipper_configuration=>flipper_config)post_installdo |installer|
react_native_post_install(installer,config[:reactNativePath],# Set `mac_catalyst_enabled` to `true` in order to apply patches# necessary for Mac Catalyst builds:mac_catalyst_enabled=>false)__apply_Xcode_12_5_M1_post_install_workaround(installer)# This is necessary for Xcode 14, because it signs resource bundles by default# when building for devices.installer.target_installation_results.pod_target_installation_results.eachdo |pod_name,target_installation_result|
target_installation_result.resource_bundle_targets.eachdo |resource_bundle_target|
resource_bundle_target.build_configurations.eachdo |config|
config.build_settings['CODE_SIGNING_ALLOWED']='NO'endendendendpost_integratedo |installer|
beginexpo_patch_react_imports!(installer)rescue=>ePod::UI.warneendendend
AppDelegate.m:
#import"AppDelegate.h"
#import<Firebase/Firebase.h>
#import<React/RCTBundleURLProvider.h>
#import<React/RCTLinkingManager.h>@implementationAppDelegate
- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// @generated begin @react-native-firebase/app-didFinishLaunchingWithOptions - expo prebuild (DO NOT MODIFY) sync-ecd111c37e49fdd1ed6354203cd6b1e2a38cccda
[FIRApp configure];
// @generated end @react-native-firebase/app-didFinishLaunchingWithOptions
self.moduleName = @"main";
// 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 [superapplication:application didFinishLaunchingWithOptions:launchOptions];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#elsereturn [[NSBundlemainBundle] URLForResource:@"main"withExtension:@"jsbundle"];
#endif
}
/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.////// @see: https://reactjs.org/blog/2022/03/29/react-v18.html/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture)./// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`.
- (BOOL)concurrentRootEnabled
{
returntrue;
}
// Linking API
- (BOOL)application:(UIApplication *)applicationopenURL:(NSURL *)urloptions:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [superapplication:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
}
// Universal Links
- (BOOL)application:(UIApplication *)applicationcontinueUserActivity:(nonnull NSUserActivity *)userActivityrestorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
return [superapplication:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
}
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
- (void)application:(UIApplication *)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
return [superapplication:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
- (void)application:(UIApplication *)applicationdidFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
return [superapplication:application didFailToRegisterForRemoteNotificationsWithError:error];
}
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
- (void)application:(UIApplication *)applicationdidReceiveRemoteNotification:(NSDictionary *)userInfofetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
return [superapplication:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
@end
Android
Click To Expand
Have you converted to AndroidX?
my application is an AndroidX application?
I am using android/gradle.settingsjetifier=true for Android compatibility?
I am using the NPM package jetifier for react-native compatibility?
android/build.gradle:
// N/A
android/app/build.gradle:
// N/A
android/settings.gradle:
// N/A
MainApplication.java:
// N/A
AndroidManifest.xml:
<!-- N/A -->
Environment
Click To Expand
react-native info output:
info Fetching system and libraries information...
System:
OS: macOS 14.2
CPU: (8) arm64 Apple M1
Memory: 128.53 MB / 8.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 21.7.2 - /var/folders/2_/p68fyjgj4x5bth46kw07t0cw0000gp/T/yarn--1718191009557-0.13425062902769413/node
Yarn: 1.22.21 - /var/folders/2_/p68fyjgj4x5bth46kw07t0cw0000gp/T/yarn--1718191009557-0.13425062902769413/yarn
npm: 10.5.0 - /opt/homebrew/bin/npm
Watchman: 2024.05.06.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.15.2 - /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 23.2, iOS 17.2, macOS 14.2, tvOS 17.2, visionOS 1.0, watchOS 10.2
Android SDK: Not Found
IDEs:
Android Studio: 2023.1 AI-231.9392.1.2311.11330709
Xcode: 15.2/15C500b - /usr/bin/xcodebuild
Languages:
Java: 11.0.22 - /opt/homebrew/opt/openjdk@11/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.2.0 => 18.2.0
react-native: 0.71.14 => 0.71.14
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
✨ Done in 6.93s.
Platform that you're experiencing the issue on:
iOS
Android
iOS but have not tested behavior on Android
Android but have not tested behavior on iOS
Both
react-native-firebase version you're using that has this issue:
19.0.1
Firebase module(s) you're using that has the issue:
i receive the notification while the app is in Background or quit but the onMessage or backgroundMessageHandler methods never trigger.
You are sending what appears to be a "mixed" content message. As such the firebase-ios-sdk underlying code will post the notification and the handler in setBackgroundMessageHandler should be called but it has some of it's own requirements - it must be async / has to return a promise or it may not be registered/called, and if the device is in low power mode or has background refresh disabled (https://rnfirebase.io/messaging/usage#ios-background-limitation) then it will not be called
Other than that, not sure why this isn't working for you if those conditions are met. You might watch what happens when the device receives the message via a look at the device log in Console.app to see how iOS and firebase-ios-sdk native code handles the FCM receipt and delivery
It appears that the problem happened only while working with the emulator while everything works fine on a real device.
Fun fact: removing the APNS header from the notification sent fixed the problem for the emulator, but caused the functions to not trigger with a real device
Issue
When on android everything works as intended while, on iOS, i receive the notification while the app is in Background or quit but the onMessage or backgroundMessageHandler methods never trigger. I added Background fetch, Remote notifications and Push notifications from Signing Capabilities in Xcode. I already set the content-available: true from the server but it doesnt seem to work.
I've already looked through a lot of workaround and solutions but nothing seems to work in my case...
App.tsx
:Also this is the code used to trigger the notification
Project Files
Javascript
Click To Expand
package.json
:firebase.json
for react-native-firebase v6:# N/A
iOS
Click To Expand
ios/Podfile
:AppDelegate.m
:Android
Click To Expand
Have you converted to AndroidX?
android/gradle.settings
jetifier=true
for Android compatibility?jetifier
for react-native compatibility?android/build.gradle
:// N/A
android/app/build.gradle
:// N/A
android/settings.gradle
:// N/A
MainApplication.java
:// N/A
AndroidManifest.xml
:<!-- N/A -->
Environment
Click To Expand
react-native info
output:react-native-firebase
version you're using that has this issue:19.0.1
Firebase
module(s) you're using that has the issue:Messaging
TypeScript
?Y
&4.9.4
React Native Firebase
andInvertase
on Twitter for updates on the library.The text was updated successfully, but these errors were encountered: