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.64k stars 2.21k forks source link

[🐛] FCM - On push notification open, causing app crash ("NSInternalInconsistencyException") #4610

Closed isbaek closed 3 years ago

isbaek commented 3 years ago

Issue

Before the IOS 14.2 update, firebase push notifications when received and tapped on by the user would correctly open the app, whether it was in foreground or background.

However, we've been receiving issues in production mode, when the push notification is received, it no longer opens the app. It is currently working fine in development however.

The error that is logged is NSInternalInconsistencyException Call must be made on main thread


Project Files

Javascript

Click To Expand

#### `package.json`: ```json "@react-native-firebase/analytics": "^6.2.0", "@react-native-firebase/app": "^6.2.0", "@react-native-firebase/messaging": "^6.2.0" ``` #### `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 platform :ios, '11.0' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' require_relative '../node_modules/react-native-unimodules/cocoapods' target 'jupiter' do # Pods for jupiter pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec" pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired" pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety" pod 'React', :path => '../node_modules/react-native/' pod 'React-Core', :path => '../node_modules/react-native/' pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules' pod 'React-Core/DevSupport', :path => '../node_modules/react-native/' pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/' pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon" pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon" pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga' pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' pod 'RNInputMask', :path => '../node_modules/react-native-text-input-mask/ios/InputMask' pod 'GoogleIDFASupport', '~> 3.14.0' use_unimodules! use_native_modules! end ``` #### `AppDelegate.m`: ```objc /** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #import "AppDelegate.h" #import #import #import "RNNotifications.h" #import #import #import #import "RNSplashScreen.h" #import #import #import #import @implementation AppDelegate @synthesize window = _window; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { if ([FIRApp defaultApp] == nil) { [FIRApp configure]; } [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self]; [RNNotifications startMonitorNotifications]; // Uncomment for test mode // [RNBranch useTestInstance]; [RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES]; [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions]; self.moduleRegistryAdapter = [[UMModuleRegistryAdapter alloc] initWithModuleRegistryProvider:[[UMModuleRegistryProvider alloc] init]]; RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"jupiter" initialProperties:nil]; rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; [super application:application didFinishLaunchingWithOptions:launchOptions]; [RNSplashScreen show]; return YES; } - (NSArray> *)extraModulesForBridge:(RCTBridge *)bridge { NSArray> *extraModules = [_moduleRegistryAdapter extraModulesForBridge:bridge]; // You can inject any extra modules that you would like here, more information at: // https://facebook.github.io/react-native/docs/native-modules-ios.html#dependency-injection return extraModules; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #ifdef DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { if (![RNBranch.branch application:app openURL:url options:options]) { if ([[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options]) { return YES; } return [RCTLinkingManager application:app openURL:url options:options]; } return YES; } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { [RNNotifications didFailToRegisterForRemoteNotificationsWithError:error]; } - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler { return [RNBranch continueUserActivity:userActivity]; } @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 11.0 CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz Memory: 84.14 MB / 8.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 12.16.0 - ~/.nvm/versions/node/v12.16.0/bin/node Yarn: 1.19.2 - /usr/local/bin/yarn npm: 6.13.4 - ~/.nvm/versions/node/v12.16.0/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman SDKs: iOS SDK: Platforms: iOS 14.2, DriverKit 20.0, macOS 11.0, tvOS 14.2, watchOS 7.1 IDEs: Android Studio: 3.4 AI-183.6156.11.34.5692245 Xcode: 12.2/12B45b - /usr/bin/xcodebuild npmPackages: react: 16.9.0 => 16.9.0 react-native: 0.61.5 => 0.61.5 ``` - **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. 6.2.0` 6.2.0 - **`Firebase` module(s) you're using that has the issue:** - `e.g. Instance ID` - **Are you using `TypeScript`?** - `Y/N` & `VERSION` N


mikehardy commented 3 years ago

Hi there! Can you please post the full stack trace? Also, have you checked the issues list in firebase-ios-sdk repo (also here on github) to see if it's deeper - in the google sdk - or here (the stack trace might also help point the way...)

hahtml commented 3 years ago

Same here. I am trying to migrate to v10 from v5 to see if it helps

isbaek commented 3 years ago

@hahtml Let me know if upgrading the versions help!

liamjones commented 3 years ago

We've just started encountering this with local notifications after upgrading RN from 0.61.5 to 0.63.3 and Xcode from 11 to 12.2.

We're still on react-native-firebase 5.5.6 currently (due to needing to migrate notifications to something else). Under the older versions of RN and Xcode, we didn't get the crash.

Here's the stack trace: https://gist.github.com/liamjones/bc22538569cb716dc1f4d94c369aa654

liamjones commented 3 years ago

As a quick fix I can wrap the completionHandler() call (https://github.com/invertase/react-native-firebase/blob/v5.5.6/ios/RNFirebase/notifications/RNFirebaseNotifications.m#L113) in a dispatch to the main thread and then it's happy.

If this is an appropriate fix does it need to be synchronous or can it be async without causing issues?

isbaek commented 3 years ago

I found out the culprit for us was coming from react-native-notifications library which we use in conjunction with Firebase v6. Upgrading the library to the latest version helped, and as @liamjones mentioned the call was wrapped to run on main thread asynchronously.

JB-CHAUVIN commented 3 years ago

Hello,

Same issue goes for me.

On iOS 14.2, when the user click sur PUSH notification, app is crashing.

Thanks,

mikehardy commented 3 years ago

To date, no one has followed my request for info:

Hi there! Can you please post the full stack trace? Also, have you checked the issues list in firebase-ios-sdk repo (also here on github) to see if it's deeper - in the google sdk - or here (the stack trace might also help point the way...)

Additional steps that are relevant in the last 20 days that my request for info has been ignored:

  1. Please confirm your underlying firebase-ios-sdk version? It should be 7.2.0, which would come in with react-native-firebase v10.2.0. If you have an override for the firebase-ios-sdk version either remove it or bump it to 7.2.0 and retest on a real device
  2. If it continues to happen reproduce it with a clean demo as it appears 3rd party libraries (mentioned above) may cause problems https://github.com/mikehardy/rnfbdemo/blob/master/make-demo.sh
  3. If it still continues to happen and the stack is in react-native-firebase you could try a main thread dispatch, if that is necessary in a fully clean reproduction we can merge a PR here if someone proposes it

Please note that I do not reproduce though. I do not think this is a react-native-firebase problem.

Further comments saying "me too" without providing any details or taking any effort to advance the discussion are worse than useless, they waste all subscribers time here. Don't do that please.

liamjones commented 3 years ago

Hi @mikehardy, I posted a full stack trace in the gist above (https://gist.github.com/liamjones/bc22538569cb716dc1f4d94c369aa654). I haven't had a chance to check the firebase-ios-sdk repo yet. This is under an older SDK though, we're still on react-native-firebase 5.5.6 as mentioned above (and using the Firebase SDK versions specified in the legacy install instructions)

mikehardy commented 3 years ago

You posted a stack vs v5 right? If so, I have disregarded it. Current versions only

Doha26 commented 3 years ago

Facing the same issue with react-native-firebase 5.6.0 and tested on iOS 14.2

here attached the stacktrace.

Capture d’écran 2021-01-06 à 13 12 30
mikehardy commented 3 years ago

I am honestly shocked anyone would be attempting to deploy react-native-firebase v5.x at this point. In strong terms I actively discourage it. You don't have access with that code base to the newer versions of the underlying firebase SDKs, and they make changes needed to adapt to the changing mobile ecosystem represented by Android 10/11 and iOS14

There will be nothing but discouragement for using v5 here, no support - with apologies, but it's a real thing: it's time to upgrade

Doha26 commented 3 years ago

Hi. @mikehardy , have applied a patch (the first answer of this stackoverflow issue https://stackoverflow.com/questions/64565093/exception-call-must-be-made-on-main-thread-ios using patch-package https://github.com/ds300/patch-package that fix the bug for now. but yes, we are planing to upgrade to v6 soon. thanks for you reply.

mikehardy commented 3 years ago

I am of course glad it's working for you :-) - I maintain things because I love hearing success stories and getting things fixed, but yes :pray: please upgrade :-)

code-by commented 3 years ago

hi, I have same issue on my project using RN Firebase 5.6 (RN 0.60.5) only for cloud messaging, to which version of RNFb I could safely painless upgrade to continue receiving push notifications in my app? thank you

mikehardy commented 3 years ago

There is no "pain free" update except from one release to the next. At this point you have a large queue of breaking changes to work through to get current on react-native-firebase and react-native. That's a technical debt you simply must pay off. Get current

code-by commented 3 years ago

@mikehardy which most recent of RNFB will work with RN 0.60.5? latest too? may be try to upgrade to v.6 for test? also do I need to reinstall pods after adding try/catch blocks into RNFirebaseNotifications.m?

mikehardy commented 3 years ago

It should work with RN60, however for you to stay on RN60 means you will not be compatible with Xcode 12.5. The oldest supported version of react-native for Xcode 12.5 is 0.63.4 I believe.

Just get to current, then none of this patch hackery will be needed. It's useful as far as it goes (I use patch-package) but just as a crutch to stay on old versions makes no sense to me. Update

skizzo commented 3 years ago

@Doha26 could you post the patch here please? The link above doesn't work for me. Thanks!

mikehardy commented 3 years ago

@skizzo the URL was in the link, it was just malformed markdown. I fixed it. But please everyone: UPDATE 🙏 - you have no idea the amount of bugs fixed between 2 years ago and now

skizzo commented 3 years ago

Thanks @mikehardy! I can only imagine how much you improved this amazing product. Unfortunately, I was unable to properly set up any version after 5.6.0 so I have to stick to what I got.

mikehardy commented 3 years ago

https://github.com/mikehardy/rnfbdemo/blob/master/make-demo.sh

clone it, read it, run it, it works?

code-by commented 3 years ago

I use Firebase (v5) only for receiving and displaying push notifications. As I understand push notifications was removed from v6+ Should I use react-native-push-notification w/o react-native-firebase or I still depend on it?

mikehardy commented 3 years ago

If you want to receive cloud messages, I think you need react-native-firebase for the app and messaging modules. If you want to display local notifications in response to those messages you will need a package that displays and manages device-local notifications, like react-native-push-notification or others

code-by commented 3 years ago

if I dont wrong our backend use following: https://fcm.googleapis.com/fcm/send https://android.googleapis.com/gcm/notification so I need continue use react-native-firebase?

mikehardy commented 3 years ago

https://fcm.googleapis.com/fcm/send

"fcm" === "Firebase Cloud Messages"

If you want to receive cloud messages, I think you need react-native-firebase for the app and messaging modules.

code-by commented 3 years ago

so for receiving FCM I need react-native-firebase and for displaying them as PushNotification 3-party lib? Previously I think it is one thing, now understand this not the same and there possibility to display PushNotification even when device not connected to the netw ))

mikehardy commented 3 years ago

Exactly that. Remote notifications are bits of JSON from internet to device Local notifications are things users can see.

They are related (remote is typically used to trigger a local) but separate.