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.63k stars 2.2k forks source link

[🐛] Android - Non-fatal Exception: io.invertase.firebase.crashlytics.d #5849

Closed Vy-Dao closed 2 years ago

Vy-Dao commented 2 years ago

Issue

The issues happen randomly when users open the app and navigate to the login screen. I'm not sure what the problem is.

app.tsx:

const AppContent = ({ routeName }: { routeName: string }): JSX.Element => {
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(loadFavoritesFromInternalStorageThunk());
  }, [dispatch]);

  return (
    <View style={styles.flex}>
      <NavigationContainer ref={navigationRef}>
        <RootStack initialRouteName={routeName} />
      </NavigationContainer>
    </View>
  );
};

export function App(props: AppProps): JSX.Element {
  const { initialRouteName } = props;
  const initialState: RootState =
    (store?.getState() as RootState) ?? rootReducer(undefined, { type: "initialize" });

  initialState.loginScreen = {
    ...initialState.loginScreen,
 };

  store = createStore(initialState);
  return (
    <Provider store={store}>
      <AppContent routeName={initialRouteName || "LoginScreen"} />
    </Provider>
  );
}

This is the picture from Firebase console image

This is the stack tray of the first bug

Non-fatal Exception: io.invertase.firebase.crashlytics.d: Invalid URL: should be a string. Was: null
       at .anonymous(.java)
       at .value(.java)
       at .value(.java)
       at .anonymous(.java)
       at .call(.java)
       at .y(.java)
       at .anonymous(.java)
       at .anonymous(.java)
       at .call(.java)
       at .y(.java)
       at .o(.java)
       at .anonymous(.java)
       at .c(.java)
       at .X(.java)
       at ._(.java)
       at .h(.java)
       at .anonymous(.java)
       at .anonymous(.java)
       at .anonymous(.java)
       at .l(.java)
       at .anonymous(.java)
       at .call(.java)
       at .y(.java)
       at .anonymous(.java)
       at .anonymous(.java)
       at .call(.java)
       at .y(.java)
       at .o(.java)
       at .anonymous(.java)
       at .c(.java)
       at .X(.java)
       at ._(.java)
       at .h(.java)
       at .anonymous(.java)
       at .anonymous(.java)
       at .anonymous(.java)
       at .onPress(.java)
       at .onPress(.java)
       at .value(.java)
       at .value(.java)
       at .onResponderRelease(.java)
       at .apply(.java)
       at .o(.java)
       at .apply(.java)
       at .h(.java)
       at .apply(.java)
       at .g(.java)
       at .b(.java)
       at .xe(.java)
       at .forEach(.java)
       at .H(.java)
       at .anonymous(.java)
       at .ke(.java)
       at ._e(.java)
       at .Re(.java)
       at .receiveTouches(.java)
       at .apply(.java)
       at .value(.java)
       at .anonymous(.java)
       at .value(.java)
       at .value(.java)

This is the stack tray of the second bug

Non-fatal Exception: io.invertase.firebase.crashlytics.d: Cannot read property 'split' of undefined
       at .n(.java)
       at .anonymous(.java)
       at .anonymous(.java)
       at .anonymous(.java)
       at .call(.java)
       at .y(.java)
       at .anonymous(.java)
       at .anonymous(.java)
       at .call(.java)
       at .y(.java)
       at .o(.java)
       at .anonymous(.java)
       at .f(.java)
       at .anonymous(.java)
       at .apply(.java)
       at .anonymous(.java)
       at .p(.java)
       at .b(.java)
       at .callImmediates(.java)
       at .value(.java)
       at .anonymous(.java)
       at .value(.java)
       at .value(.java)
       at .value(.java)

Project Files

Javascript

Click To Expand

#### `package.json`: ```json { "name": "App", "version": "0.0.1", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "start": "react-native start", }, "dependencies": { "@react-native-async-storage/async-storage": "^1.13.2", "@react-native-community/masked-view": "^0.1.6", "@react-native-firebase/analytics": "^12.9.3", "@react-native-firebase/app": "^12.9.3", "@react-native-firebase/crashlytics": "^12.9.3", "@react-native-firebase/perf": "^12.9.3", "@react-navigation/native": "^5.3.2", "@react-navigation/stack": "^5.3.6", "@reduxjs/toolkit": "^1.4.0", "apisauce": "^2.0.1", "expo-location": "^12.0.4", "html-entities": "^2.3.2", "moment": "^2.24.0", "ordinal": "^1.0.3", "prop-types": "^15.5.7", "ramda": "^0.27.0", "react": "17.0.2", "react-native": "0.66.1", "react-native-autoheight-webview": "^1.5.8", "react-native-code-push": "^7.0.1", "react-native-device-info": "^8.0.2", "react-native-gesture-handler": "1.10.3", "react-native-maps": "^0.29.0", "react-native-reanimated": "^2.0.0", "react-native-safe-area-context": "^3.0.6", "react-native-screens": "^3.3.0", "react-native-sensitive-info": "^5.5.8", "react-native-svg": "^12.1.0", "react-native-swipe-gestures": "^1.0.5", "react-native-unimodules": "^0.14.0", "react-native-webview": "^11.6.4", "react-redux": "^7.1.3", "redux": "^4.0.4", "rn-secure-storage": "^2.0.4", "semver": "^7.3.4", "validator": "^13.0.0" }, "devDependencies": { "@babel/core": "^7.12.9", "@babel/runtime": "^7.12.5", "@react-native-community/eslint-config": "^2.0.0", "@storybook/addon-storyshots": "^6.1.1", "@storybook/react": "*", "@storybook/react-native": "^5.3.23", "@types/jest": "^26.0.0", "@types/node": "^16.0.0", "@types/ramda": "^0.27.0", "@types/react-native": "^0.65.8", "@types/react-redux": "^7.1.7", "@types/redux-mock-store": "^1.0.2", "@types/semver": "^7.3.4", "@types/validator": "^13.0.0", "@typescript-eslint/eslint-plugin": "^4.14.0", "@typescript-eslint/parser": "^4.14.0", "appcenter-cli": "^2.9.0", "axios-mock-adapter": "^1.19.0", "babel-jest": "^27.0.2", "babel-loader": "^8.0.0", "detox": "^19.0.0", "eslint": "^7.14.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-prettier": "^3.1.2", "eslint-plugin-react": "^7.18.3", "eslint-plugin-react-hooks": "^4.0.4", "eslint-plugin-react-native": "^3.8.1", "eslint-plugin-react-native-a11y": "^2.0.4", "jest": "^26.6.3", "jest-circus": "^27.0.3", "jest-environment-node": "^27.0.3", "jest-trx-results-processor": "^2.0.0", "metro-react-native-babel-preset": "^0.66.0", "mocha": "^9.0.0", "patch-package": "^6.2.2", "postinstall-postinstall": "^2.1.0", "prettier": "^2.0.2", "react-devtools": "^4.12.1", "react-dom": "17.0.2", "react-native-flipper": "^0.118.0", "react-native-storybook-loader": "^2.0.2", "react-test-renderer": "^17.0.1", "redux-flipper": "^2.0.0", "redux-mock-store": "^1.5.4", "regenerator-runtime": "^0.13.5", "sloc": "^0.2.1", "typescript": "^4.1.2", "webpack": "^5.15.0" }, } ``` #### `firebase.json` for react-native-firebase v6: ```json # N/A ```

Android

Click To Expand

#### Have you converted to AndroidX? - [x] my application is an AndroidX application? - [x] 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 // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { buildToolsVersion = "30.0.2" minSdkVersion = 21 compileSdkVersion = 30 targetSdkVersion = 30 kotlinVersion = "1.5.31" ndkVersion = "21.4.7075529" } repositories { google() mavenCentral() } dependencies { classpath("com.android.tools.build:gradle:4.2.2") classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" classpath "com.google.gms:google-services:4.3.10" classpath "com.google.firebase:firebase-crashlytics-gradle:2.6.1" classpath "com.google.firebase:perf-plugin:1.4.0" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } project.ext { set("react-native", [ versions: [ // Overriding Library SDK Versions firebase: [ // Override Firebase SDK Version bom: "26.7.0" ], ], ]) } allprojects { repositories { mavenCentral() mavenLocal() 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") } maven { // All of Detox' artifacts are provided via the npm module url "$rootDir/../node_modules/detox/Detox-android" } google() maven { url "https://www.jitpack.io" } } } ``` #### `android/app/build.gradle`: ```groovy apply plugin: "com.android.application" apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.firebase.crashlytics' apply plugin: 'com.google.firebase.firebase-perf' apply from: '../../node_modules/react-native-unimodules/gradle.groovy' /** * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets * and bundleReleaseJsAndAssets). * These basically call `react-native bundle` with the correct arguments during the Android build * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the * bundle directly from the development server. */ project.ext.react = [ entryFile : "index.js", enableHermes: true, // clean and rebuild if changing ] apply from: "../../node_modules/react-native/react.gradle" apply from: "../../node_modules/react-native-code-push/android/codepush.gradle" /** * The preferred build flavor of JavaScriptCore. * * For example, to use the international variant, you can use: * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` * * The international variant includes ICU i18n library and necessary data * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that * give correct results when using with locales other than en-US. Note that * this variant is about 6MiB larger per architecture than default. */ def jscFlavor = 'org.webkit:android-jsc:+' /** * Whether to enable the Hermes VM. * * This should be set on project.ext.react and mirrored here. If it is not set * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode * and the benefits of using Hermes will therefore be sharply reduced. */ def enableHermes = project.ext.react.get("enableHermes", true) /** * Architectures to build native code for in debug. */ def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures") android { ndkVersion rootProject.ext.ndkVersion compileSdkVersion rootProject.ext.compileSdkVersion defaultConfig { applicationId "org.test.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion def buildNumber = System.getenv("BUILD_NUMBER") ?: "1" def versionNumber = System.getenv("ANDROID_VERSION") ?: "3.0.0" versionCode buildNumber.toInteger() versionName versionNumber testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' vectorDrawables.useSupportLibrary = true } signingConfigs { } buildTypes { debug { applicationIdSuffix ".dev" signingConfig signingConfigs.debug if (nativeArchitectures) { ndk { abiFilters nativeArchitectures.split(',') } } } release { minifyEnabled true signingConfig signingConfigs.debug proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" // Detox-specific additions to pro-guard proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro" ndk { debugSymbolLevel 'FULL' } } releaseuat { initWith release applicationIdSuffix ".uat" matchingFallbacks = ['release'] ndk { debugSymbolLevel 'FULL' } } } packagingOptions { pickFirst "lib/armeabi-v7a/libc++_shared.so" pickFirst "lib/arm64-v8a/libc++_shared.so" pickFirst "lib/x86/libc++_shared.so" pickFirst "lib/x86_64/libc++_shared.so" } } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:+" // From node_modules addUnimodulesDependencies() implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { exclude group: 'com.facebook.fbjni' } debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { exclude group: 'com.facebook.flipper' exclude group: 'com.squareup.okhttp3', module: 'okhttp' } debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") { exclude group: 'com.facebook.flipper' } // Detox dependencies androidTestImplementation("com.wix:detox:+") { transitive = true } androidTestImplementation "junit:junit:4.13.2" if (enableHermes) { def hermesPath = "../../node_modules/hermes-engine/android/" debugImplementation files(hermesPath + "hermes-debug.aar") releaseImplementation files(hermesPath + "hermes-release.aar") releaseuatImplementation files(hermesPath + "hermes-release.aar") } else { implementation jscFlavor } implementation 'androidx.annotation:annotation:1.1.0' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.biometric:biometric:1.1.0-rc01' implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.2' implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-preference-v14:1.0.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.viewpager:viewpager:1.0.0' implementation 'androidx.browser:browser:1.3.0' implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10' implementation 'com.google.android.material:material:1.2.1' implementation 'com.google.code.gson:gson:2.8.5' implementation 'com.google.android.gms:play-services-location:17.1.0' implementation 'com.google.android.gms:play-services-maps:17.0.0' implementation 'com.google.android.gms:play-services-auth:19.0.0' implementation 'com.google.android.gms:play-services-wallet:18.1.2' // NOTE: firebase versioning must match the versioning of individual libraries in Firebase BOM defined in android/build.gradle implementation 'com.google.firebase:firebase-core:19.0.0' implementation 'com.google.firebase:firebase-messaging:22.0.0' } // Run this once to be able to run the application with BUCK // puts all compile dependencies into folder libs for BUCK to use task copyDownloadableDepsToLibs(type: Copy) { from configurations.implementation into 'libs' } apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) ``` #### `android/settings.gradle`: ```groovy rootProject.name = 'App' apply from: '../node_modules/react-native-unimodules/gradle.groovy'; includeUnimodulesProjects() apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app', ':react-native-code-push' project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app') ``` #### `MainApplication.java`: ```java package org.app.test; import org.app.test.generated.BasePackageList; import android.app.Activity; import android.app.Application; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.widget.Toast; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.soloader.SoLoader; import org.app.test.nativemodules.AppPackage; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.List; import java.util.Map; import org.unimodules.adapters.react.ModuleRegistryAdapter; import org.unimodules.adapters.react.ReactModuleRegistryProvider; import org.unimodules.core.interfaces.SingletonModule; import com.microsoft.codepush.react.CodePush; public class MainApplication extends Application implements ReactApplication { private final ReactModuleRegistryProvider mModuleRegistryProvider = new ReactModuleRegistryProvider(new BasePackageList().getPackageList(), null); private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override protected String getJSBundleFile() { return CodePush.getJSBundleFile(); } @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List packages = new PackageList(this).getPackages(); packages.add(new AppPackage()); // Add unimodules List unimodules = Arrays.asList( new ModuleRegistryAdapter(mModuleRegistryProvider) ); packages.addAll(unimodules); return packages; } @Override protected String getJSMainModuleName() { return "index"; } }; @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; } @Override public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); } /** * Loads Flipper in React Native templates. Call this in the onCreate method with something like * initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); * * @param context * @param reactInstanceManager */ private static void initializeFlipper( Context context, ReactInstanceManager reactInstanceManager) { if (BuildConfig.DEBUG) { try { /* We use reflection here to pick up the class that initializes Flipper, since Flipper library is not available in release mode */ Class aClass = Class.forName("org.app.test.ReactNativeFlipper"); aClass .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) .invoke(null, context, reactInstanceManager); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } } ``` #### `AndroidManifest.xml`: ```xml ```


Environment

Click To Expand

**`react-native info` output:** ``` System: OS: macOS 12.0.1 CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz Memory: 4.18 GB / 32.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 16.4.2 - /usr/local/bin/node Yarn: 1.22.10 - /usr/local/bin/yarn npm: 7.18.1 - /usr/local/bin/npm Watchman: 2021.06.07.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.11.2 - /Users/admin/.rbenv/shims/pod SDKs: iOS SDK: Platforms: DriverKit 21.0.1, iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0 Android SDK: API Levels: 21, 26, 28, 29, 30, 31 Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.2, 30.0.3, 31.0.0 System Images: android-21 | android-31 Android NDK: Not Found IDEs: Android Studio: 2020.3 AI-203.7717.56.2031.7784292 Xcode: 13.1/13A1030d - /usr/bin/xcodebuild Languages: Java: 1.8.0_292 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 17.0.2 => 17.0.2 react-native: 0.66.1 => 0.66.1 react-native-macos: Not Found ``` - **Platform that you're experiencing the issue on**: - [ ] iOS - [x] 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:** - `12.9.3` - **`Firebase` module(s) you're using that has the issue:** - ``` "@react-native-firebase/analytics": "^12.9.3", "@react-native-firebase/app": "^12.9.3", "@react-native-firebase/crashlytics": "^12.9.3", "@react-native-firebase/perf": "^12.9.3", "@react-navigation/native": "^5.3.2", "@react-navigation/stack": "^5.3.6",``` - **Are you using `TypeScript`?** - `Y` - `4.1.2`


mikehardy commented 2 years ago

This is a problem in your javascript code, likely an unhandled promise rejection so it was non-fatal https://invertase.io/blog/react-native-firebase-crashlytics-configuration

There's no problem in the module, just the module has it's name in your stack trace since it is binding javascript stacks into crashlytics. Since there won't be a change in response to this, I'm going to close it, but definitely look in your project code for "split" calls on variables that might be undefined and urls that could be null