react-native-firebase icon indicating copy to clipboard operation
react-native-firebase copied to clipboard

[🐛] iOS: App crashes as soon as notification is received in foreground or clicked in background

Open imanshul opened this issue 1 year ago • 1 comments

Issue

When notification is received and app is in foreground the app crashes. The app also crashes when in background state and clicked on notification in iOS. Another problem is the listener for background/foreground message receiver are also not invoking for iOS as mentioned in rnfirebase documentation.

The stack trace when app is in foreground and app crashes:

Fatal Exception: NSInvalidArgumentException 0 CoreFoundation 0xec69c __exceptionPreprocess 1 libobjc.A.dylib 0x2bc80 objc_exception_throw 2 CoreFoundation 0x17cfdc +[NSObject(NSObject) _copyDescription] 3 CoreFoundation 0x31e08 forwarding 4 CoreFoundation 0x172950 _CF_forwarding_prep_0 5 App13Karat 0x70de50 -[RNFBMessagingUNUserNotificationCenter userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:] + 164 (RNFBMessaging+UNUserNotificationCenter.m:164) 6 WebEngage 0x14468 (Missing UUID b1bdc8ee5f553661b0f41de1dca18bc9) 7 App13Karat 0x11b7fc __FCMSwizzleDidReceiveNotificationResponseWithHandler_block_invoke + 502 (FIRMessagingRemoteNotificationsProxy.m:502) 8 App13Karat 0x119df0 FCMSwizzleDidReceiveNotificationResponseWithHandler + 552 (FIRMessagingRemoteNotificationsProxy.m:552) 9 UIKitCore 0x3a1f88 -[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion:] 10 UIKitCore 0x210958 -[UIApplication _callInitializationDelegatesWithActions:forCanvas:payload:fromOriginatingProcess:] 11 UIKitCore 0x20f504 -[UIApplication _runWithMainScene:transitionContext:completion:] 12 UIKitCore 0x20f150 -[_UISceneLifecycleMultiplexer completeApplicationLaunchWithFBSScene:transitionContext:] 13 UIKitCore 0x18bc78 _UIScenePerformActionsWithLifecycleActionMask 14 UIKitCore 0x21314c __101-[_UISceneLifecycleMultiplexer _evalTransitionToSettings:fromSettings:forceExit:withTransitionStore:]_block_invoke 15 UIKitCore 0x13abe0 -[_UISceneLifecycleMultiplexer _performBlock:withApplicationOfDeactivationReasons:fromReasons:] 16 UIKitCore 0x139658 -[_UISceneLifecycleMultiplexer _evalTransitionToSettings:fromSettings:forceExit:withTransitionStore:] 17 UIKitCore 0x138fc0 -[_UISceneLifecycleMultiplexer uiScene:transitionedFromState:withTransitionContext:] 18 UIKitCore 0x138e90 __186-[_UIWindowSceneFBSSceneTransitionContextDrivenLifecycleSettingsDiffAction _performActionsForUIScene:withUpdatedFBSScene:settingsDiff:fromSettings:transitionContext:lifecycleActionType:]_block_invoke 19 UIKitCore 0x138d98 +[BSAnimationSettings(UIKit) tryAnimatingWithSettings:fromCurrentState:actions:completion:] 20 UIKitCore 0x138620 _UISceneSettingsDiffActionPerformChangesWithTransitionContextAndCompletion 21 UIKitCore 0x1382d0 -[_UIWindowSceneFBSSceneTransitionContextDrivenLifecycleSettingsDiffAction _performActionsForUIScene:withUpdatedFBSScene:settingsDiff:fromSettings:transitionContext:lifecycleActionType:] 22 UIKitCore 0x4bc0a8 __64-[UIScene scene:didUpdateWithDiff:transitionContext:completion:]_block_invoke.225 23 UIKitCore 0x137454 -[UIScene _emitSceneSettingsUpdateResponseForCompletion:afterSceneUpdateWork:] 24 UIKitCore 0x1372c4 -[UIScene scene:didUpdateWithDiff:transitionContext:completion:] 25 UIKitCore 0x24fa48 -[UIApplication workspace:didCreateScene:withTransitionContext:completion:] 26 UIKitCore 0x24f7e0 -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:] 27 FrontBoardServices 0xf6d4 -[FBSScene _callOutQueue_didCreateWithTransitionContext:completion:] 28 FrontBoardServices 0xf570 __92-[FBSWorkspaceScenesClient createSceneWithIdentity:parameters:transitionContext:completion:]_block_invoke.108 29 FrontBoardServices 0xe19c -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] 30 FrontBoardServices 0x19f8c __92-[FBSWorkspaceScenesClient createSceneWithIdentity:parameters:transitionContext:completion:]_block_invoke 31 libdispatch.dylib 0x4300 _dispatch_client_callout 32 libdispatch.dylib 0x7d48 _dispatch_block_invoke_direct 33 FrontBoardServices 0xa520 FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK 34 FrontBoardServices 0xa4a0 -[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] 35 FrontBoardServices 0xa378 -[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] 36 CoreFoundation 0x3712c CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION 37 CoreFoundation 0x363a8 __CFRunLoopDoSource0 38 CoreFoundation 0x34bbc __CFRunLoopDoSources0 39 CoreFoundation 0x33898 __CFRunLoopRun 40 CoreFoundation 0x33478 CFRunLoopRunSpecific 41 GraphicsServices 0x34f8 GSEventRunModal 42 UIKitCore 0x22c62c -[UIApplication _run] 43 UIKitCore 0x22bc68 UIApplicationMain 44 App13Karat 0x4304 main + 8 (main.m:8) 45 ??? 0x1d27b2dcc (Missing)


Project Files

Javascript

Click To Expand

package.json:

    "@react-native-firebase/analytics": "^18.7.3",
    "@react-native-firebase/app": "^18.7.3",
    "@react-native-firebase/crashlytics": "^18.7.3",
    "@react-native-firebase/messaging": "^18.7.3",

firebase.json for react-native-firebase v6:

{
  "react-native": {
    "messaging_android_notification_channel_id": "high-priority",
    "messaging_ios_auto_register_for_remote_messages": true
  }
}

iOS

Click To Expand

ios/Podfile:

  • [ ] I'm not using Pods
  • [x] I'm using Pods and my Podfile looks like:
# Resolve react_native_pods.rb with node to allow for hoisting
# ----- Uncomment below code, if removing the react-naitve-permissions ----
# require Pod::Executable.execute_command('node', ['-p',
#   'require.resolve(
#     "react-native/scripts/react_native_pods.rb",
#     {paths: [process.argv[1]]},
#   )', __dir__]).strip

# ------ Start Used for react-native-permissions --------
def node_require(script)
  # Resolve script with node to allow for hoisting
  require Pod::Executable.execute_command('node', ['-p',
    "require.resolve(
      '#{script}',
      {paths: [process.argv[1]]},
    )", __dir__]).strip
end

node_require('react-native/scripts/react_native_pods.rb')
node_require('react-native-permissions/scripts/setup.rb')
# ------ END Used for react-native-permissions --------

platform :ios, min_ios_version_supported
prepare_react_native_project!

# ------ Start Used for react-native-permissions --------
# ⬇️ uncomment wanted permissions
setup_permissions([
  # 'AppTrackingTransparency',
  # 'Bluetooth',
  # 'Calendars',
  # 'CalendarsWriteOnly',
   'Camera',
  # 'Contacts',
  # 'FaceID',
  # 'LocationAccuracy',
  # 'LocationAlways',
  # 'LocationWhenInUse',
  # 'MediaLibrary',
  # 'Microphone',
  # 'Motion',
  # 'Notifications',
   'PhotoLibrary',
  # 'PhotoLibraryAddOnly',
  # 'Reminders',
  # 'Siri',
  # 'SpeechRecognition',
  # 'StoreKit',
])

# ------ END Used for react-native-permissions --------

# 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,...) that will be excluded
#
# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
# ```js
# module.exports = {
#   dependencies: {
#     ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
# ```
flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.disabled

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

target 'App13Karat' do
  pod 'WebEngage'
  config = use_native_modules!

  use_frameworks! :linkage => :static
  $RNFirebaseAsStaticFramework = true

  use_react_native!(
    :path => config[:reactNativePath],
    # Enables Flipper.
    #
    # Note that if you have use_frameworks! enabled, Flipper will not work and
    # you should disable the next line.
    :flipper_configuration => flipper_config,
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  target 'App13KaratTests' do
    inherit! :complete
    # Pods for testing
  end

  # ServiceExtension Target
  target 'NotificationService' do
      platform :ios, min_ios_version_supported
      pod 'WebEngageBannerPush'
  end

  # ContentExtension Target
  target 'NotificationViewController' do
    platform :ios, min_ios_version_supported
    pod 'WebEngageAppEx/ContentExtension'
  end

  post_install do |installer|
    # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
    workAroundForSharedApplication(installer)
  end
end

# Fix for MMKV after adding WebEngage, especially NotificationService and NotificationViewController as App Extension
def workAroundForSharedApplication(installer)
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'No'
        end
    end
end

AppDelegate.m:

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

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

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.moduleName = @"App13Karat";
  // 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 = @{};
  
  // Add me --- \/
    [FIRApp configure];
  // Add me --- /\
  
  //Start WebEngage
  [[WebEngage sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
  //End WebEngage

  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
  return [self getBundleURL];
}

- (NSURL *)getBundleURL
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
  return [CodePush bundleURL];
#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:

// 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:

System:
  OS: macOS 14.1.2
  CPU: (8) arm64 Apple M1
  Memory: 58.31 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.16.1
    path: ~/.nvm/versions/node/v18.16.1/bin/node
  Yarn:
    version: 1.22.17
    path: /usr/local/bin/yarn
  npm:
    version: 9.5.1
    path: ~/.nvm/versions/node/v18.16.1/bin/npm
  Watchman:
    version: 2023.12.04.00
    path: /usr/local/bin/watchman
Managers:
  CocoaPods:
    version: 1.14.3
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.0
      - iOS 17.0
      - macOS 14.0
      - tvOS 17.0
      - watchOS 10.0
  Android SDK:
    API Levels:
      - "17"
      - "23"
      - "27"
      - "28"
      - "29"
      - "30"
      - "31"
      - "33"
      - "34"
    Build Tools:
      - 29.0.2
      - 30.0.0
      - 30.0.1
      - 30.0.2
      - 30.0.3
      - 31.0.0
      - 33.0.0
      - 33.0.1
      - 34.0.0
    System Images:
      - android-26 | Google APIs ARM 64 v8a
      - android-28 | Google ARM64-V8a Play ARM 64 v8a
      - android-29 | Google Play ARM 64 v8a
      - android-30 | Google APIs ARM 64 v8a
      - android-31 | Google APIs ARM 64 v8a
      - android-32 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2023.1 AI-231.9392.1.2311.11076708
  Xcode:
    version: 15.0.1/15A507
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 11.0.11
    path: /usr/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.73.1
    wanted: 0.73.1
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

  • 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:
    • 18.7.3
  • Firebase module(s) you're using that has the issue:
    • 10.19.0
  • Are you using TypeScript?
    • N

imanshul avatar Jan 10 '24 19:01 imanshul

Very unexpected. So those lines are where we call the original notification handler delegate - if you receive a message and there was a messaging delegate configured before firebase

https://github.com/invertase/react-native-firebase/blob/970756d733e1c4642b53d91c5b1b8f58a8f5dbc0/packages/messaging/ios/RNFBMessaging/RNFBMessaging%2BUNUserNotificationCenter.m#L164-L166

the original delegate is saved here, during RNFBMessaging setup:

https://github.com/invertase/react-native-firebase/blob/970756d733e1c4642b53d91c5b1b8f58a8f5dbc0/packages/messaging/ios/RNFBMessaging/RNFBMessaging%2BUNUserNotificationCenter.m#L49

The best thing I can think of is that WebEngage (which can apparently do mobile push notification things...) is installing a delegate, and somewhere between iOS notification center, react-native-firebase code and WebEngage code there is an issue with the typing of the message received or the message receiver. [1]

  • [1] - https://developer.apple.com/forums/thread/721853?answerId=739859022#739859022

No one else has posted a crash like this before and I believe our code is just a) saving the original delegate, b) sending the original message to the original delegate so I think react-native-firebase is doing things correctly here but the problem is in the "forwarding code" which we saved and are calling.

What happens if you take out WebEngage temporarily as a test?

mikehardy avatar Jan 30 '24 17:01 mikehardy

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.

github-actions[bot] avatar Feb 27 '24 17:02 github-actions[bot]

Getting Fatal Exception: NSInvalidArgumentException -[NSObject userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:]: unrecognized selector sent to instance 0x280653020 in same behaviour .

anujmpec avatar Mar 06 '24 07:03 anujmpec

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.

github-actions[bot] avatar Apr 03 '24 09:04 github-actions[bot]