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.74k stars 2.22k forks source link

[🐛] iOS not receiving Push Notifications in DEV mode on physical device #7061

Closed brunofrigeri-lc closed 1 year ago

brunofrigeri-lc commented 1 year ago

Issue

Currently I'm using FIrebase Messaging for handling Push Notifications in my application. I'm facing some weird issue that I'm not able to receive notifications in DEV (real device) for iOS, but everything works just fine on Android.

Here's my NotificationProvider where I'm setting up permissions and registering the device apnsToken:

  const sendPushTokenAsync = async (deviceToken: string): Promise<void> => {
    await registerDeviceToApi({
      deviceRegistration: {
        platform: Platform.select({
          ios: 'apns',
          android: 'fcm',
          default: 'fcm'
        }),
        handle: deviceToken
      }
    })
  }

  const registerTokenIos = async () => {
    const permissionStatus = await messaging().requestPermission()

    const enabled =
      permissionStatus === messaging.AuthorizationStatus.AUTHORIZED ||
      permissionStatus === messaging.AuthorizationStatus.PROVISIONAL

    if (enabled) {
      const apnsToken = await messaging().getAPNSToken()

      if (apnsToken) {
        await sendPushTokenAsync(apnsToken)
      }
    }
  }

  const deleteToken = async (registrationId: string) => {
    await deleteDeviceFromApi({
      id: registrationId
    })
  }

  const registerToken = async () => {
      registerTokenIos()
  }

  useEffect(() => {
    if (authStatus === AuthStatus.AUTHENTICATED) {
      registerToken()
    }
  }, [authStatus])

Here's how I'm listening to the events:

  useEffect(() => {
    messaging().onNotificationOpenedApp(remoteMessage => {
      if (navigationRef.isReady()) {
        const navigationProps = getNavigationProps(remoteMessage)

        if (navigationProps) {
          const { screen, params } = navigationProps
          navigationRef.navigate(screen, params)
        }
      }
    })      
  }, [])

  useEffect(() => {
      messaging()
        .getInitialNotification()
        .then(remoteMessage => {
          console.log('getInitialNotification: ', remoteMessage)
          if (remoteMessage != null) {
            const navigationProps = getNavigationProps(remoteMessage)
            if (navigationProps) {
              const { screen, params } = navigationProps
              stackNavigation.navigate(screen, params)
            }
          }
        })
  }, [])

XCode logs related to FirebaseMessaging, right after building the App:

2023-04-20 11:07:07.965438-0300 LaunchControl[662:46704] 10.7.0 - [FirebaseMessaging][I-FCM001000] FIRMessaging Remote Notifications proxy enabled, will swizzle remote notification receiver handlers. If you'd prefer to manually integrate Firebase Messaging, add "FirebaseAppDelegateProxyEnabled" to your Info.plist, and set it to NO. Follow the instructions at:
2023-04-20 11:07:08.268739-0300 LaunchControl[662:46706] Connection 1: received failure notification
2023-04-20 11:07:08.380716-0300 LaunchControl[662:46741] Connection 2: received failure notification
2023-04-20 11:08:00.867582-0300 LaunchControl[662:47147] Connection 17: received failure notification

Project Files

Javascript

Click To Expand

#### `package.json`: ```json { "dependencies": { "@babel/preset-react": "^7.18.6", "@gorhom/bottom-sheet": "^4.4.3", "@microsoft/signalr": "^7.0.4", "@react-native-async-storage/async-storage": "^1.18.1", "@react-native-community/clipboard": "^1.5.1", "@react-native-community/netinfo": "^9.3.0", "@react-native-firebase/app": "^17.4.2", "@react-native-firebase/messaging": "^17.4.2", "@react-navigation/bottom-tabs": "^6.3.3", "@react-navigation/drawer": "^6.4.4", "@react-navigation/elements": "^1.3.6", "@react-navigation/native": "^6.0.12", "@react-navigation/native-stack": "^6.8.0", "@reduxjs/toolkit": "^1.8.5", "@rneui/base": "^4.0.0-rc.6", "@rneui/themed": "^4.0.0-rc.6", "@shopify/flash-list": "^1.4.2", "appcenter": "4.4.5", "appcenter-analytics": "4.4.5", "appcenter-crashes": "4.4.5", "date-fns": "^2.29.2", "formik": "^2.2.9", "lodash": "^4.17.21", "lottie-react-native": "^5.1.4", "patch-package": "^6.5.1", "query-string": "^7.1.1", "react": "18.0.0", "react-native": "0.69.4", "react-native-bootsplash": "^4.3.2", "react-native-gesture-handler": "^2.6.0", "react-native-gifted-chat": "^2.0.1", "react-native-haptic-feedback": "^1.14.0", "react-native-hyperlink": "^0.0.22", "react-native-in-app-review": "^4.2.1", "react-native-keyboard-aware-scroll-view": "^0.9.5", "react-native-linear-gradient": "^2.6.2", "react-native-modal": "^13.0.1", "react-native-pager-view": "^6.1.4", "react-native-reanimated": "^2.10.0", "react-native-redash": "^18.0.0", "react-native-safe-area-context": "^4.5.0", "react-native-screens": "^3.17.0", "react-native-skeleton-content-nonexpo": "^1.0.13", "react-native-snackbar": "^2.4.0", "react-native-svg": "^13.0.0", "react-native-tab-view": "^3.5.1", "react-native-vector-icons": "^9.2.0", "react-redux": "^8.0.2", "redux-logger": "^3.0.6", "redux-persist": "^6.0.0", "yup": "^0.32.11" } } ``` #### `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_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' platform :ios, '12.4' install! 'cocoapods', :deterministic_uuids => false # Force pods to match minimum iOS version for React Native # Fixes build issue on Xcode Cloud where some pods # Use iOS 12 calls despite being set as iOS 11 def __apply_Xcode_14_3_RC_post_install_workaround(installer) installer.pods_project.targets.each do |target| target.build_configurations.each do |config| current_target = config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] minimum_target = '12.4' if current_target.to_f < minimum_target.to_f config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = minimum_target end end end end production = ENV["PRODUCTION"] == "1" target 'LaunchControl' do config = use_native_modules! # Flags change depending on the env values. flags = get_default_flags() pod 'Firebase', :modular_headers => true pod 'FirebaseCore', :modular_headers => true pod 'FirebaseCoreInternal', :modular_headers => true pod 'GoogleUtilities', :modular_headers => true use_frameworks! :linkage => :static $RNFirebaseAsStaticFramework = true use_react_native!( :path => config[:reactNativePath], # to enable hermes on iOS, change `false` to `true` and then install pods :production => production, :hermes_enabled => flags[:hermes_enabled], :fabric_enabled => flags[:fabric_enabled], :flipper_configuration => FlipperConfiguration.enabled, # An absolute path to your application root. :app_path => "#{Pod::Config.instance.installation_root}/.." ) target 'LaunchControlTests' do inherit! :complete # Pods for testing end post_install do |installer| react_native_post_install(installer) __apply_Xcode_12_5_M1_post_install_workaround(installer) __apply_Xcode_14_3_RC_post_install_workaround(installer) end end ``` #### `AppDelegate.m`: ```objc #import "AppDelegate.h" #import #import #import #import "RNBootSplash.h" #import #import #import #import #import #import #if RCT_NEW_ARCH_ENABLED #import #import #import #import #import #import #import static NSString *const kRNConcurrentRoot = @"concurrentRoot"; @interface AppDelegate () { RCTTurboModuleManager *_turboModuleManager; RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; std::shared_ptr _reactNativeConfig; facebook::react::ContextContainer::Shared _contextContainer; } @end #endif @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { RCTAppSetupPrepareApp(application); [FIRApp configure]; RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; #if RCT_NEW_ARCH_ENABLED _contextContainer = std::make_shared(); _reactNativeConfig = std::make_shared(); _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer]; bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; #endif NSDictionary *initProps = [self prepareInitialProps]; UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"LaunchControl", initProps); if (@available(iOS 13.0, *)) { rootView.backgroundColor = [UIColor systemBackgroundColor]; } else { rootView.backgroundColor = [UIColor whiteColor]; } [AppCenterReactNative register]; [AppCenterReactNativeAnalytics registerWithInitiallyEnabled:true]; [AppCenterReactNativeCrashes registerWithAutomaticProcessing]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; [RNBootSplash initWithStoryboard:@"BootSplash" rootView:rootView]; return YES; } - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { return [RCTLinkingManager application:application openURL:url options:options]; } /// 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` feture is enabled. Otherwise, it returns `false`. - (BOOL)concurrentRootEnabled { // Switch this bool to turn on and off the concurrent root return true; } - (NSDictionary *)prepareInitialProps { NSMutableDictionary *initProps = [NSMutableDictionary new]; #ifdef RCT_NEW_ARCH_ENABLED initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]); #endif return initProps; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } #if RCT_NEW_ARCH_ENABLED #pragma mark - RCTCxxBridgeDelegate - (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge { _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self jsInvoker:bridge.jsCallInvoker]; return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager); } #pragma mark RCTTurboModuleManagerDelegate - (Class)getModuleClassFromName:(const char *)name { return RCTCoreModulesClassProvider(name); } - (std::shared_ptr)getTurboModule:(const std::string &)name jsInvoker:(std::shared_ptr)jsInvoker { return nullptr; } - (std::shared_ptr)getTurboModule:(const std::string &)name initParams: (const facebook::react::ObjCTurboModule::InitParams &)params { return nullptr; } - (id)getModuleInstanceFromClass:(Class)moduleClass { return RCTAppSetupDefaultModuleFromClass(moduleClass); } #endif @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:** ``` System: OS: macOS 13.0.1 CPU: (8) arm64 Apple M1 Memory: 53.33 MB / 16.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.10.0 - /var/folders/k9/pd215tbx0clfbm604_mk8v3w0000gn/T/yarn--1681999232417-0.0734176176719501/node Yarn: 1.22.18 - /var/folders/k9/pd215tbx0clfbm604_mk8v3w0000gn/T/yarn--1681999232417-0.0734176176719501/yarn npm: 7.24.0 - ~/.nvm/versions/node/v16.10.0/bin/npm Watchman: 2022.03.21.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.11.3 - /opt/homebrew/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.4, iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4 ``` - **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:** - `e.g. 5.4.3` - **`Firebase` module(s) you're using that has the issue:** - `e.g. Instance ID` - **Are you using `TypeScript`?** - `Y/N` & `VERSION`


github-actions[bot] commented 1 year ago

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.