React-native-firebase: [Android] 馃敟 Native crash if a push notification has been received

Created on 14 Sep 2020  路  18Comments  路  Source: invertase/react-native-firebase

Issue

Hi there. Let me describe the problem.
I am using react-native-firebase and firebase console in order to send push notifications.
But there is the issue for Android.
If the application is killed and a push notification is being received the native crash is being presented.
image


Project Files






Javascript

Click To Expand

#### `package.json`:

"@react-native-firebase/analytics": "7.5.1",
"@react-native-firebase/app": "8.4.0",
"@react-native-firebase/crashlytics": "8.4.1",
"@react-native-firebase/messaging": "7.8.1",
#### `firebase.json` for react-native-firebase v6:
{
    "react-native": {
        "crashlytics_ndk_enabled": true,
        "crashlytics_debug_enabled": true,
        "crashlytics_disable_auto_disabler": false,
        "crashlytics_auto_collection_enabled": true,

        "messaging_auto_init_enabled": true,
        "messaging_android_headless_task_timeout": 30000,
        "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:

platform :ios, '10.0'
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target '' do
  # Pods for GPGuide
  config = use_native_modules!
  use_react_native!(:path => config["reactNativePath"])

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable these next few lines.
  use_flipper!
  post_install do |installer|
    flipper_post_install(installer)
  end
end

#### `AppDelegate.m`:
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import "RNSplashScreen.h"
#import <RNBranch/RNBranch.h>
#import <ReactNativeNavigation/ReactNativeNavigation.h>
@import Firebase;
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>

#if DEBUG
#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>

static void InitializeFlipper(UIApplication *application) {
  FlipperClient *client = [FlipperClient sharedClient];
  SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
  //  [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
  [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
  [client addPlugin:[FlipperKitReactPlugin new]];
  [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
  [client start];
}
#endif
#endif

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#if DEBUG
#ifdef FB_SONARKIT_ENABLED
  InitializeFlipper(application);
#endif
#endif
  [FIRApp configure];
  NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
  [ReactNativeNavigation bootstrap:jsCodeLocation launchOptions:launchOptions];

  [RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES];

  [UNUserNotificationCenter currentNotificationCenter].delegate = self;
  UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
  UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
  [[UNUserNotificationCenter currentNotificationCenter]
   requestAuthorizationWithOptions:authOptions
   completionHandler:^(BOOL granted, NSError * _Nullable error) {
  }];
  [application registerForRemoteNotifications];

#if DEBUG
#else
  [RNSplashScreen show];
#endif

  return YES;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

// Add application:openURL:options: and application:continueUserActivity:restorationHandler: methods
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
  return [RNBranch.branch application:app openURL:url options:options] || [[UIApplication sharedApplication] openURL:url];
}

- (BOOL)application:(UIApplication *)app continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray * _Nullable))restorationHandler
{
  return [RNBranch.branch continueUserActivity:userActivity];
}

// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
  [RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
  [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
  [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// IOS 10+ Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler
{
  [RNCPushNotificationIOS didReceiveNotificationResponse:response];
  completionHandler();
}
// IOS 4-10 Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
  [RNCPushNotificationIOS didReceiveLocalNotification:notification];
}

//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}

@end


Android

Click To Expand

#### Have you converted to AndroidX? - [x] 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`:

buildscript {
    ext {
        buildToolsVersion = "29.0.2"
        minSdkVersion = 19
        compileSdkVersion = 29
        targetSdkVersion = 29

        gradleVersion = '3.5.3'
        multidexVersion = '2.0.1'
        googleServicesVersion = '4.3.3'
        playServicesBaseVersion = '17.4.0'
        shortcutBadgerVersion = '1.1.22@aar'
        frescoVersion = '2.0.0'
        animatedGifVersion = '2.0.0'
        facebookSdkVersion = '5.15.3'
        okhttpVersion = '4.4.1'
        firebaseCrashlyticsGradleVersion = '2.2.0'
        RNNKotlinVersion = '1.3.72'
        RNNKotlinStdlib = 'kotlin-stdlib-jdk8'
        swipeToRefreshLayoutVersion = '1.1.0'
    }
    repositories {
        google()
        mavenLocal()
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:$gradleVersion")
        classpath("com.google.gms:google-services:$googleServicesVersion")
        classpath("com.google.firebase:firebase-crashlytics-gradle:$firebaseCrashlyticsGradleVersion")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${RNNKotlinVersion}")
    }
}

allprojects {
    repositories {
        google()
        mavenLocal()
        maven {
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            url("$rootDir/../node_modules/jsc-android/dist")
        }
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

subprojects { subproject ->
    afterEvaluate {
        if ((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
            android {
                variantFilter { variant ->
                    def names = variant.flavors*.name
                    if (names.contains("reactNative51")
                            || names.contains("reactNative55")
                            || names.contains("reactNative56")
                            || names.contains("reactNative57")
                            || names.contains("reactNative57_5")
                            || names.contains("reactNative57WixFork")
                            || names.contains("reactNative60")) {
                        setIgnore(true)
                    }
                }
            }
        }
    }
}
#### `android/app/build.gradle`:
apply plugin: "com.android.application"
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'com.google.gms.google-services'

import com.android.build.OutputFile

/**
 * 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. Below you can see all the possible configurations
 * and their defaults. If you decide to add a configuration block, make sure to add it before the
 * `apply from: "../../node_modules/react-native/react.gradle"` line.
 *
 * project.ext.react = [
 *   // the name of the generated asset file containing your JS bundle
 *   bundleAssetName: "index.android.bundle",
 *
 *   // the entry file for bundle generation. If none specified and
 *   // "index.android.js" exists, it will be used. Otherwise "index.js" is
 *   // default. Can be overridden with ENTRY_FILE environment variable.
 *   entryFile: "index.android.js",
 *
 *   // https://reactnative.dev/docs/performance#enable-the-ram-format
 *   bundleCommand: "ram-bundle",
 *
 *   // whether to bundle JS and assets in debug mode
 *   bundleInDebug: false,
 *
 *   // whether to bundle JS and assets in release mode
 *   bundleInRelease: true,
 *
 *   // whether to bundle JS and assets in another build variant (if configured).
 *   // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
 *   // The configuration property can be in the following formats
 *   //         'bundleIn${productFlavor}${buildType}'
 *   //         'bundleIn${buildType}'
 *   // bundleInFreeDebug: true,
 *   // bundleInPaidRelease: true,
 *   // bundleInBeta: true,
 *
 *   // whether to disable dev mode in custom build variants (by default only disabled in release)
 *   // for example: to disable dev mode in the staging build type (if configured)
 *   devDisabledInStaging: true,
 *   // The configuration property can be in the following formats
 *   //         'devDisabledIn${productFlavor}${buildType}'
 *   //         'devDisabledIn${buildType}'
 *
 *   // the root of your project, i.e. where "package.json" lives
 *   root: "../../",
 *
 *   // where to put the JS bundle asset in debug mode
 *   jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
 *
 *   // where to put the JS bundle asset in release mode
 *   jsBundleDirRelease: "$buildDir/intermediates/assets/release",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in debug mode
 *   resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in release mode
 *   resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
 *
 *   // by default the gradle tasks are skipped if none of the JS files or assets change; this means
 *   // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
 *   // date; if you have any other folders that you want to ignore for performance reasons (gradle
 *   // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
 *   // for example, you might want to remove it from here.
 *   inputExcludes: ["android/**", "ios/**"],
 *
 *   // override which node gets called and with what additional arguments
 *   nodeExecutableAndArgs: ["node"],
 *
 *   // supply additional arguments to the packager
 *   extraPackagerArgs: []
 * ]
 */

project.ext.react = [
        enableHermes: true,  // clean and rebuild if changing
]

apply from: "../../node_modules/react-native/react.gradle"

/**
 * Set this to true to create two separate APKs instead of one:
 *   - An APK that only works on ARM devices
 *   - An APK that only works on x86 devices
 * The advantage is the size of the APK is reduced by about 4MB.
 * Upload all the APKs to the Play Store and people will download
 * the correct one based on the CPU architecture of their device.
 */
def enableSeparateBuildPerCPUArchitecture = false

/**
 * Run Proguard to shrink the Java bytecode in release builds.
 */
def enableProguardInReleaseBuilds = false

/**
 * 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);

android {
    compileSdkVersion rootProject.ext.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        applicationId ""
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        missingDimensionStrategy "RNN.reactNativeVersion", "reactNative62"
        versionCode
        versionName ""
        multiDexEnabled true

        manifestPlaceholders = [
        ]
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
        }
    }
    signingConfigs {
        release {
            storeFile file(GPGUIDE_STORE_FILE)
            storePassword GPGUIDE_STORE_PASSWORD
            keyAlias GPGUIDE_KEY_ALIAS
            keyPassword GPGUIDE_KEY_PASSWORD
        }
    }
    buildTypes {
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://facebook.github.io/react-native/docs/signed-apk-android.
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }
    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"
    }
    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // https://developer.android.com/studio/build/configure-apk-splits.html
            def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }

        }
    }

    packagingOptions {
        pickFirst '**/armeabi-v7a/libc++_shared.so'
        pickFirst '**/x86/libc++_shared.so'
        pickFirst '**/arm64-v8a/libc++_shared.so'
        pickFirst '**/x86_64/libc++_shared.so'
        pickFirst '**/x86/libjsc.so'
        pickFirst '**/armeabi-v7a/libjsc.so'
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    //noinspection GradleDynamicVersion
    implementation "com.facebook.react:react-native:+"  // From node_modules
    implementation "androidx.multidex:multidex:${rootProject.ext.multidexVersion}"
    implementation "com.facebook.fresco:fresco:${rootProject.ext.frescoVersion}"
    implementation "com.facebook.fresco:animated-gif:${rootProject.ext.animatedGifVersion}"
    implementation "com.facebook.android:facebook-android-sdk:${rootProject.ext.facebookSdkVersion}"
    implementation "com.google.android.gms:play-services-base:${rootProject.ext.playServicesBaseVersion}"
    implementation "me.leolin:ShortcutBadger:${rootProject.ext.shortcutBadgerVersion}"
    implementation(platform("com.squareup.okhttp3:okhttp-bom:${rootProject.ext.okhttpVersion}"))
    implementation("com.squareup.okhttp3:okhttp")
    implementation("com.squareup.okhttp3:okhttp-urlconnection")

    implementation "androidx.swiperefreshlayout:swiperefreshlayout:${rootProject.ext.swipeToRefreshLayoutVersion}"
    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'
    }

    if (enableHermes) {
        def hermesPath = "../../node_modules/hermes-engine/android/";
        debugImplementation files(hermesPath + "hermes-debug.aar")
        releaseImplementation files(hermesPath + "hermes-release.aar")
    } else {
        implementation jscFlavor
    }
}

// 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.compile
    into 'libs'
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
#### `android/settings.gradle`:
rootProject.name = ''
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)

include ':app'
#### `MainApplication.java`:
import android.content.Context;

import androidx.multidex.MultiDex;

import com.facebook.react.PackageList;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import com.reactnativenavigation.NavigationApplication;
import com.reactnativenavigation.react.NavigationReactNativeHost;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

import io.branch.referral.Branch;

public class MainApplication extends NavigationApplication {
    private final ReactNativeHost mReactNativeHost =
            new NavigationReactNativeHost(this) {
                @Override
                public boolean getUseDeveloperSupport() {
                    return BuildConfig.DEBUG;
                }

                @Override
                protected List<ReactPackage> getPackages() {
                    @SuppressWarnings("UnnecessaryLocalVariable")
                    List<ReactPackage> packages = new PackageList(this).getPackages();
                    // Packages that cannot be autolinked yet can be added manually here, for example:
                    // packages.add(new MyReactNativePackage());
                    return packages;
                }

                @Override
                protected String getJSMainModuleName() {
                    return "index";
                }
            };

    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Branch.getAutoInstance(this);
        Branch.getInstance().setBranchRemoteInterface(new BranchNetworkClient());
        MultiDex.install(this);
        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("");
                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`:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="com.android.vending.BILLING" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <permission
        android:name="${applicationId}.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />

    <application
        android:name=".MainApplication"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_security_config"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning"
        tools:replace="android:allowBackup">
        <activity
            android:name=".MainActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:windowSoftInputMode="adjustPan">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <data android:scheme="branchandroid" />
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
            </intent-filter>
            <intent-filter
                android:autoVerify="true"
                tools:targetApi="m">
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:host="gpguide.app.link"
                    android:scheme="https" />
            </intent-filter>
        </activity>
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
        <activity
            android:name="com.facebook.FacebookActivity"
            android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
            android:label="@string/app_name" />
        <activity
            android:name="com.facebook.CustomTabActivity"
            android:exported="true">
            <intent-filter tools:ignore="AppLinkUrlError">
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
            </intent-filter>
        </activity>

        <meta-data
            android:name="io.branch.sdk.BranchKey"
            android:value="${BRANCH_IO_PROD_API_KEY}" />
        <meta-data
            android:name="io.branch.sdk.BranchKey.test"
            android:value="${BRANCH_IO_DEV_API_KEY}" />
        <meta-data
            android:name="io.branch.sdk.TestMode"
            android:value="false" />
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@mipmap/ic_notification" />
        <meta-data
                tools:replace="android:resource"
            android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/colorAccent" />
        <meta-data
                tools:replace="android:value"
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="@string/gp_guide_notification_channel" />
        <meta-data
            android:name="com.samsung.android.icon_container.has_icon_container"
            android:value="true" />

<!--        <receiver-->
<!--            android:name="io.branch.referral.InstallListener"-->
<!--            android:exported="true">-->
<!--            <intent-filter>-->
<!--                <action android:name="com.android.vending.INSTALL_REFERRER" />-->
<!--            </intent-filter>-->
<!--        </receiver>-->

    </application>

</manifest>


Environment

Click To Expand

**`react-native info` output:**

System:
    OS: macOS 10.15.6
    CPU: (8) x64 Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz
    Memory: 1020.88 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 14.4.0 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.7 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.9.3 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.7, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
      Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.1
      System Images: android-29 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom, android-30 | Google APIs Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 4.0 AI-193.6911.18.40.6626763
    Xcode: 11.7/11E801a - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_232 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.13.1 => 16.13.1 
    react-native: 0.63.2 => 0.63.2 
  npmGlobalPackages:
    *react-native*: 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:** - `8.4.0` - **`Firebase` module(s) you're using that has the issue:** - `Crashlytics, Messaging` - **Are you using `TypeScript`?** - `N`




Needs Triage Bug Needs Review

Most helpful comment

@mikehardy i've checked the similar issues, but there is only a similar issue for v. 5x.
Yes, I also tried to disable Hermes and the issue was the same

All 18 comments

There are a few of these, have you checked the existing issues?
Does this still happen if you disable Hermes and use JSC?

@mikehardy i've checked the similar issues, but there is only a similar issue for v. 5x.
Yes, I also tried to disable Hermes and the issue was the same

@mikehardy a few more details:
1) I am using topics in order to filter push notifications
2) I was able to catch the crash if I sent a message to ios and android devices, without topics, and with some topic

@mikehardy I can't remember the similar crash on the version < 6

Please post the exact JSON sent via the admin SDK (but minus any API or device tokens!) so we can try to reproduce

@mikehardy you mean google-services.json ?
i don't use any 3rd party backend and send the notifications directly through firebase console

No I mean the JSON that you are sending - for messaging troubleshooting the firebase console is ineffective, use the firebase admin jdk via node, so that you can precisely control the JSON being sent and know that you are 1) getting reproducible payloads sent and 2) can share the payload you are sending with others.

As mentioned above though, of course do not include the API keys or device tokens, for security reasons - when reproducing issues we can use our own API keys and device tokens

@mikehardy how and where could I do it?

use the firebase admin jdk via node, so that you can precisely control the JSON being sent

@dmitryusikriseapps exactly like that - it is well documented by google

@dmitryusikriseapps I'm not sure if this will help, but I was facing a similar issue, and the following seems to have resolved it for me:

  1. Make sure your emulator has Google Play
  2. Remove <service> from AndroidManifest.xml
  3. Place onMessage in it's own useEffect

For me, the most helpful thing was making sure my emulator was running Google Play. I needed to spin up a new one, but I found it mentioned in the Send a Test Message section of the Firebase Docs.

Also, in trying to figure out why I could receive messages on iOS, _but not Android_, I started going through the Firebase Docs for Receive Messages and saw this about editing the app manifest. So I added that <service> code, but it turns out, _I didn't need it. In fact, it was ultimately causing issues for me._

Finally, I had the onMessage logic in the same useEffect as onNotificationOpenedApp and getInitialNotification. For some reason, this would crash my app. I would briefly see the alert generated (as suggested in the RNF docs), but then the app would crash. Putting onMessage in it's own useEffect seems to have done the trick.

Hope this helps...

Ps - shout out to @mikehardy for all the hard work 馃挭, RNF is a game changer!

2. Remove <service> from AndroidManifest.xml

It`s working for me

@Sirzs After removing of <service> from AndroidManifest.xml
it's does not affect any changes and app crash when open notification

_AndroidManifest.xml_

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="******">
    - - - - - - - - - - - - - 
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

    - - - - - - - -

    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
    <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher"
                 android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false"
                 android:theme="@style/AppTheme">
      - - - - - - - -  - - -
        <activity android:name=".MainActivity" android:label="@string/app_name"
                  android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
                  android:launchMode="singleTask" android:windowSoftInputMode="adjustResize"
                  android:theme="@style/Theme.App.SplashScreen" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
                <data android:scheme="com.myapp"/>
                <data android:scheme="myapp"/>
            </intent-filter>
        </activity>
        <activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
                  android:theme="@style/Base.Theme.AppCompat"/>
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
        <uses-library android:name="org.apache.http.legacy" android:required="false"/>

        <meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground"
                   android:value="false"/>
        <!-- Change the resource name to your App's accent color - or any other color you want -->
        <meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
                   android:resource="@color/white"/> <!-- or @android:color/{name} to use a standard color -->

        <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions"/>
        <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher"/>
        <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
                <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
            </intent-filter>
        </receiver>

<!--        <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"-->
<!--                 android:exported="false">-->
<!--            <intent-filter>-->
<!--                <action android:name="com.google.firebase.MESSAGING_EVENT"/>-->
<!--            </intent-filter>-->
<!--        </service>-->
    </application>
</manifest>

_android/build.gradle_

buildscript {
    ext {
        buildToolsVersion = "29.0.2"
        minSdkVersion = 21
        compileSdkVersion = 29
        targetSdkVersion = 29
        supportLibVersion = "28.0.0"
        playServicesVersion = "17.0.0"
        androidMapsUtilsVersion = "0.6.2"
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:3.5.3")

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        classpath 'com.google.gms:google-services:4.3.3'
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.2.0'
    }
}

allprojects {
    repositories {
        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")
        }

        google()
        jcenter()
        maven { url 'https://www.jitpack.io' }
    }
}

_Error output_

image

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 the community's attention?

This issue will be closed in 15 days if no further activity occurs.
Thank you for your contributions.

The solution for me was to implement setBackgroundMessageHandler at the level where you're registering the app. I passed an empty Promise.resolve since I'm not performing any tasks in the background. It appears that when a notification is triggered whilst the app is not running (completely quit) it attempts to run a headless task so if a handler is not set it throws.

messaging().setBackgroundMessageHandler(() => Promise.resolve());

That is really unexpected @shaddeen but I'm not sure I've ever tested that case. I have a handler set in my app for that hook so I would not have seen the "negative test" of no handler. I'll mark this for review and the test I need to try to reproduce is to send what exactly to my app on android with no handler set? Do you have a clean JSON that you can share which you post to the REST API so I could know I'm sending the same cloud message contents? Of course remove your API key and device token, but this is the best way to share reproductions with cloud messages so we use the same JSON

@mikehardy To summarise:

  • No background handler set
  • Make sure app has been quit
  • Send a noisy notification to the device
  • Open via notification
  • Observe crash

I'll try and get that json for you asap.

Remove the below code from the AndroidManifest.xml

<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
 <service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service> 

Add


<receiver android:name="io.invertase.firebase.notifications.RNFirebaseNotificationReceiver"></receiver>
<receiver android:enabled="true" android:exported="true"  android:name="io.invertase.firebase.notifications.RNFirebaseNotificationsRebootReceiver"></receiver>

https://stackoverflow.com/questions/64195649/app-crashes-after-receiving-notification-using-react-native-firebase-messaging/64206973#64206973

@JanakiNarayanan

Remove the below code from the AndroidManifest.xml

<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
 <service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service> 

You should have nothing in your AndroidManifest.xml to remove if you followed the v5 to v6 migration guide: https://rnfirebase.io/migrating-to-v6#removing-from-android-manifest

Add


<receiver android:name="io.invertase.firebase.notifications.RNFirebaseNotificationReceiver"></receiver>
<receiver android:enabled="true" android:exported="true"  android:name="io.invertase.firebase.notifications.RNFirebaseNotificationsRebootReceiver"></receiver>

https://stackoverflow.com/questions/64195649/app-crashes-after-receiving-notification-using-react-native-firebase-messaging/64206973#64206973

This is terrible advice. If you do that you will not receive anything as you no longer have an intent filter.

Better would be to open a fresh issue, with a reproduction based on current stable versions, and a stack trace from adb logcat.

This issue is not attracting high quality information and is I believe mixed among several different things now.

I am going to close it.

Anyone suffering a native crash please follow the issue template and provide a stack trace from adb logcat based on current versions and ideally from a clean demonstration app built with https://github.com/mikehardy/rnfbdemo/blob/master/make-demo.sh

Was this page helpful?
0 / 5 - 0 ratings