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.
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
#### `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
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>
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`
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:
<service>
from AndroidManifest.xml
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>
fromAndroidManifest.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_
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:
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>
@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>
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
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