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

[🐛] Crashlytics not reporting crash in Debug and not honouring setCrashlyticsCollectionEnabled #8453

Open
2 of 10 tasks
nmehlei opened this issue Apr 7, 2025 · 1 comment

Comments

@nmehlei
Copy link

nmehlei commented Apr 7, 2025

Issue

Firebase Crashlytics does not actually crash when invoking crashlytics().crash() and no crashes are being reported in Firebase's Crashlytics dashboard.

In our case, Firebase.json does indeed disable firebase (see snippets below), yet this is being enabled via setCrashlyticsCollectionEnabled() after app start. This needs to be opt-in due to GDPR compliance, yet based on logs this is confirmed to be enabled almost instantly after app start.

Our full initialization code looks as follows:

public async initialize(): Promise<void> {
    return new Promise<void>(async (resolve, reject) => {
        let crashReportingEnabled = environment.crashReporting.enabled;

        if(!crashReportingEnabled)
            this.logger.info('Crash reporting is disabled based on configuration');

        await crashlytics().setCrashlyticsCollectionEnabled(!crashReportingEnabled);

        if(await crashlytics().didCrashOnPreviousExecution()) {
            console.warn('Crashlytics reports that the app crashed on a previous execution');
        }

        if(await crashlytics().checkForUnsentReports()) {
            if(crashReportingEnabled) {
                crashlytics().sendUnsentReports();
                this.logger.info('Sent previously unsent crash reports');
            } else {
                this.logger.warn('There are unsent crash reports that cannot be sent since crash reporting is disabled');
            }
        }

        resolve();
    });
}

The issue happens for both Android & iOS. In the case of iOS, the crashlytics-related logs show that Firebase assumes it is disabled, hence it somehow does not seem to make use of the setting above. Also, yes, I did run pod install after firebase.json change.

2025-04-07 16:29:25.568 Db TestApp (Dev)[37163:484422] [com.apple.defaults:User Defaults] found no value for key crashlytics_debug_enabled in CFPrefsSearchListSource<0x600002c07e80> (Domain: io.invertase.firebase, Container: (null))
2025-04-07 16:29:25.568 Df TestApp (Dev)[37163:484422] (TestApp (Dev).debug.dylib) +[RNFBSharedUtils getConfigBooleanValue:key:defaultValue:] [Line 155] RNFBCrashlyticsInit crashlytics_debug_enabled via RNFBJSON: 1
2025-04-07 16:29:25.568 Df TestApp (Dev)[37163:484422] (TestApp (Dev).debug.dylib) +[RNFBSharedUtils getConfigBooleanValue:key:defaultValue:] [Line 165] RNFBCrashlyticsInit crashlytics_debug_enabled final value: 1
2025-04-07 16:29:25.569 Db TestApp (Dev)[37163:484422] [com.apple.defaults:User Defaults] looked up value 0 for key crashlytics_auto_collection_enabled in CFPrefsPlistSource<0x600002c0cf00> (Domain: io.invertase.firebase, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null), Contents Need Refresh: No) via CFPrefsSearchListSource<0x600002c07e80> (Domain: io.invertase.firebase, Container: (null))
2025-04-07 16:29:25.569 Db TestApp (Dev)[37163:484422] [com.apple.defaults:User Defaults] looked up value 0 for key crashlytics_auto_collection_enabled in CFPrefsPlistSource<0x600002c0cf00> (Domain: io.invertase.firebase, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null), Contents Need Refresh: No) via CFPrefsSearchListSource<0x600002c07e80> (Domain: io.invertase.firebase, Container: (null))
2025-04-07 16:29:25.569 Db TestApp (Dev)[37163:484422] [com.apple.defaults:User Defaults] looked up value 0 for key crashlytics_auto_collection_enabled in CFPrefsPlistSource<0x600002c0cf00> (Domain: io.invertase.firebase, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null), Contents Need Refresh: No) via CFPrefsSearchListSource<0x600002c07e80> (Domain: io.invertase.firebase, Container: (null))
2025-04-07 16:29:25.569 Db TestApp (Dev)[37163:484422] [com.apple.defaults:User Defaults] looked up value 0 for key crashlytics_auto_collection_enabled in CFPrefsPlistSource<0x600002c0cf00> (Domain: io.invertase.firebase, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null), Contents Need Refresh: No) via CFPrefsSearchListSource<0x600002c07e80> (Domain: io.invertase.firebase, Container: (null))
2025-04-07 16:29:25.569 Df TestApp (Dev)[37163:484422] (TestApp (Dev).debug.dylib) +[RNFBSharedUtils getConfigBooleanValue:key:defaultValue:] [Line 150] RNFBCrashlyticsInit crashlytics_auto_collection_enabled via RNFBPreferences: 0
2025-04-07 16:29:25.569 Df TestApp (Dev)[37163:484422] (TestApp (Dev).debug.dylib) +[RNFBSharedUtils getConfigBooleanValue:key:defaultValue:] [Line 165] RNFBCrashlyticsInit crashlytics_auto_collection_enabled final value: 0
2025-04-07 16:29:25.570 I  TestApp (Dev)[37163:484422] [com.facebook.react.log:native] Crashlytics - INFO: crashlytics collection is not enabled, not crashing.

<!-- For bonus points, if you put a 🔥 (:fire:) emojii at the start of the issue title we'll know -->
<!-- that you took the time to fill this out correctly, or, at least read this far -->

Project Files

Javascript

Click To Expand

package.json:

{
  "name": "TestApp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "lint": "eslint .",
    "start": "react-native start",
  },
  "dependencies": {
    "@invertase/react-native-apple-authentication": "2.4.0",
    "@microsoft/react-native-clarity": "4.1.8",
    "@react-native-async-storage/async-storage": "2.1.2",
    "@react-native-firebase/analytics": "21.13.0",
    "@react-native-firebase/app": "21.13.0",
    "@react-native-firebase/auth": "21.13.0",
    "@react-native-firebase/crashlytics": "21.13.0",
    "@react-native-firebase/perf": "21.13.0",
    "@react-native-google-signin/google-signin": "13.2.0",
    "@react-navigation/bottom-tabs": "^7.3.6",
    "@react-navigation/native": "^7.1.2",
    "@react-navigation/native-stack": "^7.3.6",
    "@stripe/stripe-react-native": "0.43.0",
    "date-fns": "4.1.0",
    "react": "19.0.0",
    "react-native": "0.78.2",
    "react-native-blob-util": "0.21.2",
    "react-native-bootsplash": "6.3.4",
    "react-native-fbsdk-next": "13.4.1",
    "react-native-geolocation-service": "5.3.1",
    "react-native-linear-gradient": "2.8.3",
    "react-native-maps": "1.21.0-alpha.141",
    "react-native-pdf-renderer": "1.6.0",
    "react-native-safe-area-context": "5.3.0",
    "react-native-screens": "4.10.0",
    "react-native-share": "12.0.9",
    "react-native-vector-icons": "10.2.0",
    "source-sans": "3.46.0",
    "uuid-random": "1.3.2",
    "zustand": "5.0.3"
  },
  "devDependencies": {
    "@babel/core": "^7.25.2",
    "@babel/preset-env": "^7.25.3",
    "@babel/runtime": "^7.25.0",
    "@react-native-community/cli": "latest",
    "@react-native-community/cli-platform-android": "17.0.0",
    "@react-native-community/cli-platform-ios": "17.0.0",
    "@react-native/babel-preset": "0.78.2",
    "@react-native/eslint-config": "0.78.2",
    "@react-native/metro-config": "0.78.2",
    "@react-native/typescript-config": "0.78.2",
    "@testing-library/react-native": "^13.2.0",
    "@types/jest": "^29.5.14",
    "@types/react": "^19.0.0",
    "@types/react-native-vector-icons": "^6.4.18",
    "@types/react-test-renderer": "^19.0.0",
    "eslint": "^8.57.0",
    "icon-set-creator": "^1.2.6",
    "jest": "^29.7.0",
    "jest-junit": "^16.0.0",
    "prettier": "2.8.8",
    "react-test-renderer": "19.0.0",
    "typescript": "5.0.4"
  },
  "engines": {
    "node": ">=18"
  },
  "packageManager": "[email protected]"
}

firebase.json for react-native-firebase v6:

{
    "react-native": {
      "crashlytics_auto_collection_enabled": false,
      "crashlytics_debug_enabled": true,
      "crashlytics_disable_auto_disabler": true,
      "perf_auto_collection_enabled": false
    }
  }

iOS

Click To Expand

ios/Podfile:

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

platform :ios, min_ios_version_supported
prepare_react_native_project!

# 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

plugin 'cocoapods-user-defined-build-types'

enable_user_defined_build_types!

project 'TestApp',
  'TestingDebug' => :debug,
  'TestingRelease' => :release,
  'StagingDebug' => :debug,
  'StagingRelease' => :release,
  'ProductionDebug' => :debug,
  'ProductionRelease' => :release

target 'TestApp' do
  config = use_native_modules!

  use_react_native!(
    :path => config[:reactNativePath],
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  pod "Firebase", :build_type => :dynamic_framework
  pod "FirebaseCoreInternal", :build_type => :dynamic_framework
  pod "FirebaseCore", :build_type => :dynamic_framework
  pod 'GoogleUtilities', :build_type => :dynamic_framework

  # NOTE: added because of https://github.com/react-native-maps/react-native-maps/blob/master/docs/installation.md
  rn_maps_path = '../node_modules/react-native-maps'
  pod 'react-native-maps', :path => rn_maps_path   #, :subspecs => ['google-maps']
  pod 'react-native-google-maps', :path => rn_maps_path
  pod 'react-native-maps-generated', :path => rn_maps_path

  # NOTE: added because of https://github.com/RonRadtke/react-native-blob-util#readme
  pod 'react-native-blob-util', :path => '../node_modules/react-native-blob-util'

  # NOTE: added because of: https://rnfirebase.io/#altering-cocoapods-to-use-frameworks
  # use_frameworks! :linkage => :static
  $RNFirebaseAsStaticFramework = true

  # NOTE: based on
#   pre_install do |installer|
#     installer.pod_targets.each do |pod|
#         if pod.name.eql?('react-native-maps') || pod.name.eql?('react-native-google-maps') || pod.name.eql?('react-native-maps-generated')
#             def pod.build_type;
#                 Pod::BuildType.static_library
#             end
#         end
#     end
#   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,
      # :ccache_enabled => true
    )

    # NOTE: based on https://stackoverflow.com/a/58367269
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.1'
        end
    end

    # installer.pods_project.targets.each do |target|
    #     target.build_configurations.each do |config|
    #         config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = "arm64"
    #     end
    # end
  end
end

AppDelegate.swift:

import UIKit
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider

// NOTE: added because of: https://rnfirebase.io/#configure-firebase-with-ios-credentials
import Firebase

// NOTE: added because of https://github.com/zoontek/react-native-bootsplash
import RNBootSplash

// NOTE: added because of https://github.com/thebergamo/react-native-fbsdk-next
import FBSDKCoreKit

// NOTE: added because of react-native-maps based on their example
import GoogleMaps

@main
class AppDelegate: RCTAppDelegate {
  override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    self.moduleName = "TestApp"
    self.dependencyProvider = RCTAppDependencyProvider()

    // NOTE: added because of: https://rnfirebase.io/#configure-firebase-with-ios-credentials
    FirebaseApp.configure()

    // NOTE: added because of react-native-maps based on their example
    GMSServices.provideAPIKey("redacted")

    // 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 = [:]

    // NOTE: added because of https://github.com/thebergamo/react-native-fbsdk-next
    ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  override func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
        return ApplicationDelegate.shared.application(application, open: url, options: options) ||
               GIDSignIn.sharedInstance.handle(url) ||
               RCTLinkingManager.application(application, open: url, options: options)
    }

    override func application(
        _ application: UIApplication,
        continue userActivity: NSUserActivity,
        restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
    ) -> Bool {
        return RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
    }

  // NOTE: added because of https://github.com/zoontek/react-native-bootsplash
  override func customize(_ rootView: RCTRootView!) {
      super.customize(rootView)
      RNBootSplash.initWithStoryboard("BootSplash", rootView: rootView) // ⬅️ initialize the splash screen
    }

  override func sourceURL(for bridge: RCTBridge) -> URL? {
    self.bundleURL()
  }

  override func bundleURL() -> URL? {
#if DEBUG
    RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
    Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
  }
}


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:

pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
plugins { id("com.facebook.react.settings") }
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
rootProject.name = 'TestApp'
include ':app'
includeBuild('../node_modules/@react-native/gradle-plugin')

MainApplication.java:

package net.testapp.app

import android.app.Application
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.react.soloader.OpenSourceMergedSoMapping
import com.facebook.soloader.SoLoader

class MainApplication : Application(), ReactApplication {

  override val reactNativeHost: ReactNativeHost =
      object : DefaultReactNativeHost(this) {
        override fun getPackages(): List<ReactPackage> =
            PackageList(this).packages.apply {
              // Packages that cannot be autolinked yet can be added manually here, for example:
              // add(MyReactNativePackage())
            }

        override fun getJSMainModuleName(): String = "index"

        override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG

        override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
        override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
      }

  override val reactHost: ReactHost
    get() = getDefaultReactHost(applicationContext, reactNativeHost)

  override fun onCreate() {
    super.onCreate()
    SoLoader.init(this, OpenSourceMergedSoMapping)
    if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
      // If you opted-in for the New Architecture, we load the native entry point for this app.
      load()
    }
  }
}

AndroidManifest.xml:

<!-- N/A -->


Environment

Click To Expand

react-native info output:

System:
  OS: macOS 15.3.1
  CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
  Memory: 1.70 GB / 32.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.19.0
    path: ~/.nvm/versions/node/v18.19.0/bin/node
  Yarn:
    version: 1.22.22
    path: ~/.nvm/versions/node/v18.19.0/bin/yarn
  npm:
    version: 10.2.3
    path: ~/.nvm/versions/node/v18.19.0/bin/npm
  Watchman:
    version: 2024.08.12.00
    path: /usr/local/bin/watchman
Managers:
  CocoaPods:
    version: 1.16.2
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.2
      - iOS 18.2
      - macOS 15.2
      - tvOS 18.2
      - visionOS 2.2
      - watchOS 11.2
  Android SDK:
    API Levels:
      - "28"
      - "30"
      - "31"
      - "32"
      - "33"
      - "34"
      - "35"
    Build Tools:
      - 30.0.2
      - 30.0.3
      - 31.0.0
      - 32.0.0
      - 32.1.0
      - 33.0.0
      - 33.0.1
      - 34.0.0
      - 35.0.0
    System Images:
      - android-26 | Google APIs Intel x86 Atom
      - android-26 | Google APIs Intel x86_64 Atom
      - android-28 | Google APIs Intel x86 Atom
      - android-30 | Intel x86_64 Atom
      - android-30 | Google APIs Intel x86 Atom
      - android-30 | Google APIs Intel x86_64 Atom
      - android-30 | Google Play Intel x86 Atom
      - android-31 | Google APIs Intel x86_64 Atom
      - android-32 | Google APIs Intel x86_64 Atom
      - android-33 | Google APIs Intel x86_64 Atom
      - android-34 | Google APIs Intel x86_64 Atom
      - android-35 | Google APIs Intel x86_64 Atom
    Android NDK: Not Found
IDEs:
  Android Studio: 2024.2 AI-242.23339.11.2421.12700392
  Xcode:
    version: 16.2/16C5032a
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 11.0.22
    path: /usr/local/opt/openjdk@11/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.0
    wanted: latest
  react:
    installed: 19.0.0
    wanted: 19.0.0
  react-native:
    installed: 0.78.2
    wanted: 0.78.2
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true
  • 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:
    • 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

@mikehardy
Copy link
Collaborator

I don't reproduce this - I just added some infrastructure in our e2e app specifically to re-enable crash testing after our migration of the e2e app to New Architecture. It works for me.

https://invertase.io/blog/react-native-firebase-crashlytics-configuration is the integration and testing process walk through

To see what I see:

git clone [email protected]:invertase/react-native-firebase
cd react-native-firebase
yarn
yarn lerna:prepare
yarn tests:android:build && yarn tests:ios:pod:install && yarn tests:ios:build
yarn tests:emulator:start # note this will consume one terminal
yarn tests:packager:jet # note this will consume one terminal
yarn tests:android:test # at any point while it's running, hit one of the two crash buttons
yarn tests:ios:test # at any point while it's running, hit one of the two crash buttons

Please see if that works for you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants