invertase / react-native-firebase

🔥 A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
https://rnfirebase.io
Other
11.61k stars 2.19k forks source link

[🐛] iOS - onMessage and setBackgroundMessageHandler not triggering #7840

Closed KongReply closed 2 months ago

KongReply commented 2 months ago

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:

export const NAVIGATION_PERSISTENCE_KEY = "NAVIGATION_STATE"

const NAVIGATION_IDS = ["login", "home", "notifications"]

// Web linking configuration
const prefixes = Linking.createURL("")
const config = {
  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",
      },
    },
  },
}

interface AppProps {
  hideSplashScreen: () => Promise<void>
}

/**
 * This is the root component of our app.
 */
function App(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) return null

  // 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"
  // }

  const linking = {
    prefixes,
    config,
    async getInitialURL() {
      const url = await Linking.getInitialURL()
      if (typeof url === "string") {
        return url
      }
      // 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) {
      const onReceiveURL = ({ url }: { url: string }) => listener(url)

      // Listen to incoming links from deep linking
      const linkingSubscription = 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.
      const unsubscribe = 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(async msg => {
    console.log("AAAA", msg)
    NotificationStorage.setItem("isNewNotification", true)
  })

  messaging().onMessage(async remoteMessage => {
    console.log("ON MESSAGE")
    NotificationStorage.setItem("isNewNotification", true)
  });

  // otherwise, we're ready to render the app
  return (
    <RootSiblingParent>
      <BottomSheetModalProvider>
        <SafeAreaProvider initialMetrics={initialWindowMetrics}>
          <ErrorBoundary catchErrors={Config.catchErrors}>
            <ApiProvider api={apiSlice}>
              <GestureHandlerRootView style={{ flex: 1 }}>
                <AppNavigator
                  linking={linking}
                  /* initialState={initialNavigationState}
          onStateChange={onNavigationStateChange} */
                />
              </GestureHandlerRootView>
            </ApiProvider>
          </ErrorBoundary>
        </SafeAreaProvider>
      </BottomSheetModalProvider>
    </RootSiblingParent>
  )
}

export default App

Also this is the code used to trigger the notification

message = messaging.MulticastMessage(
            data=payload,
            notification=messaging.Notification(payload["name"], payload["body"]),
            apns=messaging.APNSConfig(headers={"apns-priority": "10"}, payload=messaging.APNSPayload(aps=messaging.Aps(content_available=True))),
            tokens=tokens,
        )

Project Files

Javascript

Click To Expand

#### `package.json`: ```json { "name": "example", "version": "0.0.1", "private": true, "scripts": { "start": "expo start --dev-client", "ios": "react-native run-ios", "ios:dev": "NODE_ENV=development react-native run-ios --scheme \"A2AEnergyHub dev\"", "ios:prod": "NODE_ENV=production react-native run-ios --scheme \"A2AEnergyHub prod\"", "android": "react-native run-android --active-arch-only", "android:dev": "ENVFILE=.env.dev && react-native run-android --mode=devdebug", "android:dev-release": "ENVFILE=.env.dev && react-native run-android --mode=devrelease", "android:prod": "ENVFILE=.env.prod && react-native run-android --mode=proddebug", "android:prod-release": "ENVFILE=.env.prod && react-native run-android --mode=prodrelease", "android:aab-dev": "ENVFILE=.env.dev && cd android/ && ./gradlew assembleDevRelease", "android:aab-prod": "ENVFILE=.env.prod && cd android/ && ./gradlew assembleProdRelease", "compile": "tsc --noEmit -p . --pretty", "format": "prettier --write \"app/**/*.{js,jsx,json,md,ts,tsx}\"", "lint": "eslint index.js App.js app test --fix --ext .js,.ts,.tsx", "patch": "patch-package", "test": "jest", "test:watch": "jest --watch", "adb": "adb reverse tcp:9090 tcp:9090 && adb reverse tcp:3000 tcp:3000 && adb reverse tcp:9001 tcp:9001 && adb reverse tcp:8081 tcp:8081", "bundle:ios": "react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ios/main.jsbundle --assets-dest ios", "bundle:android": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res", "bundle:visualize": "npx react-native-bundle-visualizer", "bundle:visualize:dev": "npx react-native-bundle-visualizer --dev", "release:ios": "echo 'Not implemented yet: release:ios. Use Xcode. More info: https://reactnative.dev/docs/next/publishing-to-app-store'", "release:android": "cd android && rm -rf app/src/main/res/drawable-* && ./gradlew assembleRelease && cd - && echo 'APK generated in ./android/app/build/outputs/apk/release/app-release.apk'", "clean": "npx react-native-clean-project", "clean-all": "npx react-native clean-project-auto", "expo:start": "expo start", "expo:android": "expo start --android", "expo:ios": "expo start --ios", "expo:web": "expo start --web", "prebuild": "expo prebuild --clean", "codegen": "graphql-codegen --config codegen.ts" }, "overrides": { "react-error-overlay": "6.0.9" }, "dependencies": { "@expo-google-fonts/maven-pro": "^0.2.3", "@expo/metro-config": "^0.10.7", "@expo/webpack-config": "^18.0.1", "@forgerock/javascript-sdk": "^4.3.0", "@gorhom/bottom-sheet": "^4.6.0", "@react-native-async-storage/async-storage": "1.17.11", "@react-native-firebase/analytics": "^19.0.1", "@react-native-firebase/app": "^19.0.1", "@react-native-firebase/auth": "^19.0.1", "@react-native-firebase/messaging": "^19.0.1", "@react-native-firebase/storage": "^19.0.1", "@react-navigation/bottom-tabs": "^6.3.2", "@react-navigation/native": "^6.0.2", "@react-navigation/native-stack": "^6.0.2", "@react-navigation/stack": "^6.3.20", "@reduxjs/toolkit": "^2.1.0", "date-fns": "^2.29.2", "date-holidays": "^3.23.12", "expo": "~48.0.21", "expo-application": "~5.1.1", "expo-auth-session": "~4.0.3", "expo-build-properties": "^0.11.1", "expo-constants": "~14.2.1", "expo-device": "~5.2.1", "expo-file-system": "~15.2.2", "expo-font": "~11.1.1", "expo-image-picker": "~14.1.1", "expo-linking": "~4.0.1", "expo-localization": "~14.1.1", "expo-modules-core": "~1.2.3", "expo-splash-screen": "~0.18.2", "expo-status-bar": "~1.4.4", "expo-web-browser": "~12.1.1", "formik": "^2.4.5", "i18n-js": "3.9.2", "jotai": "^2.4.3", "moment": "^2.30.1", "node-emoji": "^2.1.3", "react": "18.2.0", "react-native": "0.71.14", "react-native-bootsplash": "^4.7.5", "react-native-calendars": "^1.1304.1", "react-native-config": "^1.5.1", "react-native-copilot": "^3.3.0", "react-native-element-dropdown": "^2.10.1", "react-native-emoji": "^1.8.0", "react-native-exit-app": "^2.0.0", "react-native-fast-image": "^8.6.3", "react-native-gesture-handler": "~2.9.0", "react-native-linear-gradient": "2.5.6", "react-native-markdown-display": "^7.0.2", "react-native-mmkv": "^2.10.2", "react-native-pager-view": "6.1.2", "react-native-reanimated": "~2.14.4", "react-native-render-html": "^6.3.4", "react-native-root-siblings": "^5.0.1", "react-native-root-toast": "^3.5.1", "react-native-safe-area-context": "4.5.0", "react-native-screens": "~3.20.0", "react-native-svg": "12.1.0", "react-native-tracking-transparency": "^0.1.2", "react-native-ui-datepicker": "^2.0.1", "react-native-ui-lib": "^7.16.0", "react-native-walkthrough-tooltip": "^1.6.0", "react-native-webview": "11.26.0", "react-query": "^3.39.3", "react-redux": "^9.1.0", "yup": "^1.3.3" }, "devDependencies": { "@babel/core": "^7.20.0", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", "@graphql-codegen/cli": "3.1.0", "@graphql-codegen/client-preset": "2.1.0", "@graphql-codegen/import-types-preset": "^2.2.6", "@graphql-codegen/introspection": "3.0.1", "@graphql-codegen/typescript": "^3.0.1", "@graphql-codegen/typescript-operations": "^3.0.1", "@graphql-codegen/typescript-react-apollo": "^3.3.7", "@graphql-codegen/typescript-react-query": "^4.1.0", "@react-native-community/cli-platform-ios": "^8.0.2", "@rnx-kit/metro-config": "^1.3.5", "@rnx-kit/metro-resolver-symlinks": "^0.1.26", "@types/i18n-js": "3.8.2", "@types/jest": "^29.2.1", "@types/react": "~18.0.27", "@types/react-test-renderer": "^18.0.0", "@typescript-eslint/eslint-plugin": "^5.59.0", "@typescript-eslint/parser": "^5.59.0", "babel-jest": "^29.2.1", "babel-loader": "8.2.5", "babel-plugin-root-import": "^6.6.0", "eslint": "8.17.0", "eslint-config-prettier": "8.5.0", "eslint-config-standard": "17.0.0", "eslint-plugin-import": "2.26.0", "eslint-plugin-n": "^15.0.0", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "6.0.0", "eslint-plugin-react": "7.30.0", "eslint-plugin-react-native": "4.0.0", "expo-modules-autolinking": "~1.1.0 || ~1.2.0", "fbjs-scripts": "3.0.1", "jest": "^29.2.1", "jest-circus": "29", "jest-environment-node": "29", "jest-expo": "^49.0.0", "metro": "^0.80.8", "metro-config": "0.75.1", "metro-core": "^0.80.8", "metro-react-native-babel-preset": "0.75.1", "metro-source-map": "0.75.1", "mocha": "^10.2.0", "patch-package": "6.4.7", "postinstall-prepare": "1.0.1", "prettier": "2.8.8", "query-string": "^7.0.1", "react-devtools-core": "^4.28.5", "react-dom": "18.2.0", "react-native-web": "~0.18.7", "react-test-renderer": "18.2.0", "regenerator-runtime": "^0.13.4", "ts-jest": "29", "typescript": "^4.9.4" }, "resolutions": { "@types/react": "^18", "@types/react-dom": "^18" }, "engines": { "node": ">=18" }, "prettier": { "printWidth": 100, "semi": false, "singleQuote": false, "trailingComma": "all" }, "eslintConfig": { "root": true, "parser": "@typescript-eslint/parser", "extends": [ "plugin:@typescript-eslint/recommended", "plugin:react/recommended", "plugin:react-native/all", "standard", "prettier", "plugin:react-hooks/recommended", "plugin:prettier/recommended" ], "plugins": [ "@typescript-eslint", "react", "react-native" ], "parserOptions": { "ecmaFeatures": { "jsx": true }, "project": "./tsconfig.json" }, "settings": { "react": { "pragma": "React", "version": "detect" } }, "globals": { "__DEV__": false, "jasmine": false, "beforeAll": false, "afterAll": false, "beforeEach": false, "afterEach": false, "test": false, "expect": false, "describe": false, "jest": false, "it": false }, "rules": { "@typescript-eslint/ban-ts-ignore": 0, "@typescript-eslint/ban-ts-comment": 0, "@typescript-eslint/explicit-function-return-type": 0, "@typescript-eslint/explicit-member-accessibility": 0, "@typescript-eslint/explicit-module-boundary-types": 0, "@typescript-eslint/indent": 0, "@typescript-eslint/member-delimiter-style": 0, "@typescript-eslint/no-empty-interface": 0, "@typescript-eslint/no-explicit-any": 0, "@typescript-eslint/no-object-literal-type-assertion": 0, "@typescript-eslint/no-var-requires": 0, "@typescript-eslint/no-inferrable-types": 0, "@typescript-eslint/no-unused-vars": [ "error", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" } ], "comma-dangle": 0, "multiline-ternary": 0, "no-undef": 0, "no-unused-vars": 0, "no-use-before-define": 0, "no-global-assign": 0, "quotes": 0, "react-native/no-raw-text": 0, "react-native/no-inline-styles": 0, "react-native/no-color-literals": 0, "react/no-unescaped-entities": 0, "react/prop-types": 0, "space-before-function-paren": 0, "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "error" } } } ``` #### `firebase.json` for react-native-firebase v6: ```json # N/A ```

iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ```ruby require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods") require File.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' if podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR'] == 'true' platform :ios, podfile_properties['ios.deploymentTarget'] || '14.0' install! 'cocoapods', :deterministic_uuids => false prepare_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.disabled if ENV['NO_FLIPPER'] == '1' then # Explicitly disabled through environment variables flipper_config = FlipperConfiguration.disabled elsif podfile_properties.key?('ios.flipper') then # Configure Flipper in Podfile.properties.json if podfile_properties['ios.flipper'] == 'true' then flipper_config = FlipperConfiguration.enabled(["Debug", "Release"]) elsif podfile_properties['ios.flipper'] != 'false' then flipper_config = FlipperConfiguration.enabled(["Debug", "Release"], { 'Flipper' => podfile_properties['ios.flipper'] }) end end target 'A2AEnergyHub' do use_expo_modules! config = use_native_modules! use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks'] use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['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 dependencies pod '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_install do |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 .each do |pod_name, target_installation_result| target_installation_result.resource_bundle_targets.each do |resource_bundle_target| resource_bundle_target.build_configurations.each do |config| config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' end end end end post_integrate do |installer| begin expo_patch_react_imports!(installer) rescue => e Pod::UI.warn e end end end ``` #### `AppDelegate.m`: ```objc #import "AppDelegate.h" #import #import #import @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(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 [super application:application didFinishLaunchingWithOptions:launchOptions]; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else return [[NSBundle mainBundle] 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 { return true; } // Linking API - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options]; } // Universal Links - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler { BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result; } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { return [super application:application didFailToRegisterForRemoteNotificationsWithError:error]; } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { return [super application: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.settings` `jetifier=true` for Android compatibility? - [ ] I am using the NPM package `jetifier` for react-native compatibility? #### `android/build.gradle`: ```groovy // N/A ``` #### `android/app/build.gradle`: ```groovy // N/A ``` #### `android/settings.gradle`: ```groovy // N/A ``` #### `MainApplication.java`: ```java // N/A ``` #### `AndroidManifest.xml`: ```xml ```


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**: - [X] 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:** - `Messaging` - **Are you using `TypeScript`?** - `Y` & `4.9.4`


mikehardy commented 2 months ago

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

KongReply commented 2 months ago

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