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

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

Closed
2 of 10 tasks
KongReply opened this issue Jun 12, 2024 · 2 comments
Closed
2 of 10 tasks
Labels
help: needs-triage Issue needs additional investigation/triaging. type: bug New bug report

Comments

@KongReply
Copy link

KongReply commented Jun 12, 2024

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:

{
  "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:

# N/A

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:
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:

#import "AppDelegate.h"
#import <Firebase/Firebase.h>

#import <React/RCTBundleURLProvider.h>
#import <React/RCTLinkingManager.h>

@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<UIApplicationOpenURLOptionsKey,id> *)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<id<UIUserActivityRestoring>> * _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:

// 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:
    • Messaging
  • Are you using TypeScript?
    • Y & 4.9.4


@KongReply KongReply added help: needs-triage Issue needs additional investigation/triaging. type: bug New bug report labels Jun 12, 2024
@mikehardy
Copy link
Collaborator

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
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help: needs-triage Issue needs additional investigation/triaging. type: bug New bug report
Projects
None yet
Development

No branches or pull requests

2 participants