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

[🐛] 🔥Crashlytics Implementation not detecting crashes on IOS #7056

Closed eugenioxcastro closed 1 year ago

eugenioxcastro commented 1 year ago

Issue

Describe your issue here

After following all installation guides our react native app sucesfully recorded errors and crashes on Android devices, however, none have been recorded for our IOS devices. Our app is not returning any errors when building it. All the needed libraries have been added. The crashlytics module is not having an effect on IOS. The project is compiling and no errors are shown, but functions like crashlytics().crash() or crashlytics().recordError(error) are not doing anything.

Context: We've been using other firebase modules for a while, such as app, authentication, storage and messaging. They have all worked as expected on IOS and Android.


Project Files

Javascript

Click To Expand

#### `package.json`: ```json "@react-native-firebase/app": "^17.3.0", "@react-native-firebase/auth": "^17.3.0", "@react-native-firebase/crashlytics": "17.3.0", "@react-native-firebase/messaging": "^17.3.0", "@react-native-firebase/storage": "^17.3.0", ``` #### `firebase.json` for react-native-firebase v6: ```json { "react-native": { "crashlytics_debug_enabled": true, "crashlytics_disable_auto_disabler": true, "crashlytics_auto_collection_enabled": true, "crashlytics_is_error_generation_on_js_crash_enabled": true, "crashlytics_javascript_exception_handler_chaining_enabled": true } } ``` #### Implementation in our Error Boundary ```js import React, { Component } from 'react'; import { View, Image, StyleSheet, Platform } from 'react-native'; import LinearGradient from 'react-native-linear-gradient'; import { SafeAreaView } from 'react-native-safe-area-context'; import crashlytics from '@react-native-firebase/crashlytics'; import environment from '../../environments/environment'; import Text from '../ui/Text'; class ErrorBoundary extends Component { constructor(props) { super(props); this.state = { hasError: false, }; } static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, errorInfo) { this.setState({ hasError: true }); const versionNumber = environment.VERSION_NUMBER; crashlytics().setAttributes({ name: `Boundary Error - ${error}`, appVersion: versionNumber, OSVersion: Platform.OS, }); crashlytics().log(errorInfo.componentStack); crashlytics().recordError(error); } render() { if (this.state.hasError) { return (...) } } ```

iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ```ruby `$RNFirebaseAsStaticFramework = true require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' platform :ios, '13.0' install! 'cocoapods', :deterministic_uuids => false target 'App' do config = use_native_modules! # Flags change depending on the env values. flags = get_default_flags() use_react_native!( :path => config[:reactNativePath], # to enable hermes on iOS, change `false` to `true` and then install pods :hermes_enabled => flags[:hermes_enabled], :fabric_enabled => flags[:fabric_enabled], # An absolute path to your application root. :app_path => "#{Pod::Config.instance.installation_root}/.." ) target 'appTests' do inherit! :complete # Pods for testing end target 'App-Development' do inherit! :complete # Pods for testing end # Enables Flipper. # # Note that if you have use_frameworks! enabled, Flipper will not work and # you should disable the next line. # use_flipper!() use_frameworks! post_install do |installer| react_native_post_install(installer) __apply_Xcode_12_5_M1_post_install_workaround(installer) end end` ``` #### `AppDelegate.m`: ```objc `#import "AppDelegate.h" #import #import #import #import #import #if RCT_NEW_ARCH_ENABLED #import #import #import #import #import #import #import @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 { [FIRApp configure]; RCTAppSetupPrepareApp(application); 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 // UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"App", nil); // Changed type of rootView to RCTRootView instead of UIView. // Typed case RCTAppSetupDefaultRootView as well. RCTRootView *rootView = (RCTRootView *)RCTAppSetupDefaultRootView(bridge, @"app", nil); if (@available(iOS 13.0, *)) { rootView.backgroundColor = [UIColor systemBackgroundColor]; } else { rootView.backgroundColor = [UIColor whiteColor]; } self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; // Added code to handle mid blank screen while react loads. // Made sure the name matches the one used for the storyboard file UIStoryboard *launchScreenStoryboard = [UIStoryboard storyboardWithName:@"Launch Screen" bundle:nil]; // Matches the Storyboard ID we chose for our View Controller UIViewController *launchScreenViewController = [launchScreenStoryboard instantiateViewControllerWithIdentifier:@"LaunchScreenViewController"]; UIView *launchScreenView = [launchScreenViewController view]; launchScreenView.frame = self.window.bounds; rootView.loadingView = launchScreenView; return YES; } - (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 `import org.apache.tools.ant.taskdefs.condition.Os // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { buildToolsVersion = "31.0.0" minSdkVersion = 21 compileSdkVersion = 31 targetSdkVersion = 31 if (System.properties['os.arch'] == "aarch64") { // For M1 Users we need to use the NDK 24 which added support for aarch64 ndkVersion = "24.0.8215888" } else { // Otherwise we default to the side-by-side NDK version from AGP. ndkVersion = "21.4.7075529" } } repositories { google() mavenCentral() } dependencies { classpath("com.android.tools.build:gradle:7.0.4") classpath("com.facebook.react:react-native-gradle-plugin") classpath("de.undercouch:gradle-download-task:4.1.2") // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files // firebase classpath 'com.google.gms:google-services:4.3.14' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2' } } allprojects { repositories { maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm url("$rootDir/../node_modules/react-native/android") } maven { // Android JSC is installed from npm url("$rootDir/../node_modules/jsc-android/dist") } mavenCentral { // We don't want to fetch react-native from Maven Central as there are // older versions over there. content { excludeGroup "com.facebook.react" } } google() maven { url 'https://www.jitpack.io' } } } ` ``` #### `android/app/build.gradle`: ```groovy apply plugin: "com.android.application" apply plugin: 'com.google.gms.google-services' // Firebase apply plugin: 'com.google.firebase.crashlytics' ... buildTypes { debug { signingConfig signingConfigs.debug } release { // Caution! In production, you need to generate your own keystore file. // see https://reactnative.dev/docs/signed-apk-android. signingConfig signingConfigs.debug minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" firebaseCrashlytics { nativeSymbolUploadEnabled true unstrippedNativeLibsDir 'build/intermediates/merged_native_libs/release/out/lib' } } } ... ``` #### `android/settings.gradle`: ```groovy rootProject.name = 'app' apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app' includeBuild('../node_modules/react-native-gradle-plugin') if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") { include(":ReactAndroid") project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid') } ``` #### `MainApplication.java`: ```java // N/A ``` #### `AndroidManifest.xml`: ```xml ```


Environment

Click To Expand

**`react-native info` output:** ``` System: OS: Windows 10 10.0.22000 CPU: (8) x64 Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz Memory: 4.65 GB / 15.81 GB Binaries: Node: 16.13.0 - C:\Program Files\nodejs\node.EXE Yarn: Not Found npm: 8.19.2 - C:\Program Files\nodejs\npm.CMD Watchman: Not Found SDKs: Android SDK: API Levels: 31, 33 Build Tools: 30.0.2, 30.0.3, 31.0.0, 33.0.0 System Images: android-31 | Intel x86 Atom_64, android-31 | Google APIs Intel x86 Atom_64, android-33 | Google Play Intel x86 Atom_64 Android NDK: Not Found Windows SDK: AllowDevelopmentWithoutDevLicense: Enabled AllowAllTrustedApps: Enabled IDEs: Android Studio: AI-213.7172.25.2113.9123335 Visual Studio: 17.0.32014.148 (Visual Studio Enterprise 2022) Languages: Java: 18.0.1.1 npmPackages: @react-native-community/cli: Not Found react: 17.0.2 => 17.0.2 react-native: 0.68.2 => 0.68.2 react-native-windows: Not Found npmGlobalPackages: *react-native*: Not Found ``` - **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:** - `0.68.2` - **`Firebase` module(s) you're using that has the issue:** - `Crashlytics "17.3.0"` - **Are you using `TypeScript`?** - `N`


MikeAlvarado commented 1 year ago

Bumping for any info regarding this.

matetuh commented 1 year ago

In our case, it looks like the package does not read the settings from the firebase.json file, so that crashlytics are disabled (according to the default settings). firebase.json settings:

{
  "react-native": {
    "crashlytics_debug_enabled": true,
    "crashlytics_disable_auto_disabler": true,
    "crashlytics_auto_collection_enabled": true,
    "crashlytics_is_error_generation_on_js_crash_enabled": true,
    "crashlytics_javascript_exception_handler_chaining_enabled": true
  },
  "$schema": "./node_modules/@react-native-firebase/app/firebase-schema.json"
}

The logs from Xcode make this clear:

2023-05-09 15:09:41.393734+0200 proj_name[26924:156171] +[RNFBSharedUtils getConfigBooleanValue🔑defaultValue:] [Line 157] RNFBCrashlyticsInit crashlytics_debug_enabled via RNFBMeta: 0
2023-05-09 15:09:41.393858+0200 proj_name[26924:156171] +[RNFBSharedUtils getConfigBooleanValue🔑defaultValue:] [Line 160] RNFBCrashlyticsInit crashlytics_debug_enabled final value: 0
2023-05-09 15:09:41.393936+0200 proj_name[26924:156171] +[RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled] [Line 49] RNFBCrashlyticsInit isCrashlyticsCollectionEnabled after checking crashlytics_debug_enabled: 0
2023-05-09 15:09:41.394039+0200 proj_name[26924:156171] [native] Crashlytics - INFO: crashlytics collection is not enabled, not crashing.

Only by enabling them with the patch (screenshot below), the app can crash and sends notifications to the firebase console. image

LechKulesza commented 1 year ago

Same issue as above for me :/ With patch crashlytics works but without it it doesn't.

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.