React-native-firebase: 馃敟 Can't get setBackgroundMessageHandler to work in RNFB v6 on Android

Created on 29 Oct 2019  路  21Comments  路  Source: invertase/react-native-firebase

Issue

In react-native-firebase v6, I can't get setBackgroundMessageHandler to work in my app. Notifications are received just fine but the handler is not executed.

I have done it like in the guide to no avail.

import { AppRegistry } from 'react-native';
import messaging from '@react-native-firebase/messaging';
import AsyncStorage from '@react-native-community/async-storage';
import App from './App';
import { name as appName } from './app.json';

messaging().setBackgroundMessageHandler(async ({ data: { title, message } }) => {
    console.log('in background');
    // Save the notification locally
    const notificationList = JSON.parse(await AsyncStorage.getItem('@SM_NOTIFICATIONS')) || [];
    notificationList.push({ title, message, isRead: false });
    await AsyncStorage.setItem('@SM_NOTIFICATIONS', JSON.stringify(notificationList));
});

AppRegistry.registerComponent(appName, () => App);

Nothing happened beside the incoming notifications. I expected the code to save the incoming notifications in AsyncStorage.


Project Files






iOS

Click To Expand

#### `ios/Podfile`: - [x] I'm not using Pods - [ ] I'm using Pods and my Podfile looks like:

# N/A
#### `AppDelegate.m`:
// N/A


Android

Click To Expand

#### Have you converted to AndroidX? - [ ] my application is an AndroidX application? - [x] I am using `android/gradle.settings` `jetifier=true` for Android compatibility? - [x] I am using the NPM package `jetifier` for react-native compatibility? #### `android/build.gradle`:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        buildToolsVersion = "28.0.3"
        minSdkVersion = 21
        compileSdkVersion = 28
        targetSdkVersion = 28
        supportLibVersion = "28.0.0"
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.0'
        classpath 'com.google.gms:google-services:4.3.2'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        google()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}


// task wrapper(type: Wrapper) {
wrapper {
    gradleVersion = '4.7'
    distributionUrl = distributionUrl.replace("bin", "all")
}
#### `android/app/build.gradle`:
apply plugin: "com.android.application"

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
 *   entryFile: "index.android.js",
 *
 *   // 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 = [
    entryFile: "index.js"
]

apply from: '../../node_modules/react-native-unimodules/gradle.groovy'
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

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion

    defaultConfig {
        applicationId "com.smonline"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 2
        versionName "0.1"
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk true  // If true, also generate a universal APK
            include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
        }
    }
    signingConfigs {
        release {
            storeFile file(SM_RELEASE_STORE_FILE)
            storePassword SM_RELEASE_STORE_PASSWORD
            keyAlias SM_RELEASE_KEY_ALIAS
            keyPassword SM_RELEASE_KEY_PASSWORD
        }
    }
    buildTypes {
        release {
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            signingConfig signingConfigs.release
        }
    }
    // 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:
            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
            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
            }
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation 'com.google.firebase:firebase-analytics:17.2.0'
    // implementation 'com.google.firebase:firebase-core:16.0.7'
    implementation 'com.google.firebase:firebase-messaging:20.0.0'
    // implementation "com.google.firebase:firebase-iid:17.0.4"
    implementation project(path: ":@react-native-firebase_app")
    implementation project(path: ":@react-native-firebase_messaging")
    implementation project(':react-native-webview')
    implementation project(':@react-native-community_async-storage')
    implementation project(':@react-native-community_netinfo')
    implementation project(':react-native-screens')
    implementation project(':react-native-reanimated')
    implementation project(':react-native-gesture-handler')
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
    implementation "com.facebook.react:react-native:+"  // From node_modules
    addUnimodulesDependencies()
}

// 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 plugin: 'com.google.gms.google-services'
#### `android/settings.gradle`:
apply from: '../node_modules/react-native-unimodules/gradle.groovy'
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
include ':@react-native-community_async-storage'
project(':@react-native-community_async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android')
include ':@react-native-community_netinfo'
project(':@react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android')
include ':react-native-screens'
project(':react-native-screens').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-screens/android')
include ':react-native-reanimated'
project(':react-native-reanimated').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-reanimated/android')
include ':react-native-gesture-handler'
project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-gesture-handler/android')
includeUnimodulesProjects()

rootProject.name = 'smonline'

include ':@react-native-firebase_app'
project(':@react-native-firebase_app').projectDir = new File(rootProject.projectDir, './../node_modules/@react-native-firebase/app/android')
include ':@react-native-firebase_messaging'
project(':@react-native-firebase_messaging').projectDir = new File(rootProject.projectDir, './../node_modules/@react-native-firebase/messaging/android')

include ':app'
#### `MainApplication.java`:
package com.smonline;

import android.app.Application;

import io.invertase.firebase.app.ReactNativeFirebaseAppPackage;
import io.invertase.firebase.messaging.ReactNativeFirebaseMessagingPackage;

import com.facebook.react.ReactApplication;
import com.reactnativecommunity.webview.RNCWebViewPackage;
import com.reactnativecommunity.asyncstorage.AsyncStoragePackage;
import com.reactnativecommunity.netinfo.NetInfoPackage;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.smonline.generated.BasePackageList;
import com.swmansion.reanimated.ReanimatedPackage;
import com.swmansion.rnscreens.RNScreensPackage;
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;

import org.unimodules.adapters.react.ReactAdapterPackage;
import org.unimodules.adapters.react.ModuleRegistryAdapter;
import org.unimodules.adapters.react.ReactModuleRegistryProvider;
import org.unimodules.core.interfaces.Package;
import org.unimodules.core.interfaces.SingletonModule;
import expo.modules.constants.ConstantsPackage;
import expo.modules.permissions.PermissionsPackage;
import expo.modules.filesystem.FileSystemPackage;

import java.util.Arrays;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {
    private final ReactModuleRegistryProvider mModuleRegistryProvider = new ReactModuleRegistryProvider(
            new BasePackageList().getPackageList(), Arrays.<SingletonModule>asList());

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

        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                new MainReactPackage(),
                new RNCWebViewPackage(),
                new AsyncStoragePackage(),
                new NetInfoPackage(),
                new ReactNativeFirebaseAppPackage(),
                new ReactNativeFirebaseMessagingPackage(),
                new ReanimatedPackage(),
                new RNGestureHandlerPackage(),
                new RNScreensPackage(),
                new ModuleRegistryAdapter(mModuleRegistryProvider)
            );
        }

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

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

    @Override
    public void onCreate() {
        super.onCreate();
        SoLoader.init(this, /* native exopackage */ false);
    }
}
#### `AndroidManifest.xml`:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.smonline">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

    <!-- OPTIONAL PERMISSIONS, REMOVE WHATEVER YOU DO NOT NEED -->
    <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
    <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
    <!-- <uses-permission android:name="android.permission.READ_PHONE_STATE" /> -->
    <uses-permission android:name="android.permission.USE_FINGERPRINT" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

    <!-- These require runtime permissions on M -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!-- <uses-permission android:name="android.permission.CAMERA" /> -->
    <!-- <uses-permission android:name="android.permission.READ_CONTACTS" /> -->
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!-- <uses-permission android:name="android.permission.RECORD_AUDIO" /> -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <!-- END OPTIONAL PERMISSIONS -->

    <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"
      android:usesCleartextTraffic="true">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>


Environment

Click To Expand

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

React Native Environment Info:
    System:
      OS: Linux 4.15 Ubuntu 18.04.3 LTS (Bionic Beaver)
      CPU: (4) x64 AMD A8-4500M APU with Radeon(tm) HD Graphics
      Memory: 882.89 MB / 7.28 GB
      Shell: 4.4.20 - /bin/bash
    Binaries:
      Node: 10.16.0 - ~/opt/node/bin/node
      Yarn: 1.5.1 - ~/.yarn/bin/yarn
      npm: 6.12.0 - ~/opt/node/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    npmPackages:
      react: 16.8.3 => 16.8.3 
      react-native: 0.59.10 => 0.59.10 
    npmGlobalPackages:
      react-native-cli: 2.0.1
- **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:** - `6.0.2` - **`Firebase` module(s) you're using that has the issue:** - `Messaging` - **Are you using `TypeScript`?** - `N`



Android Messaging >= 6

Most helpful comment

Your example JSON is not a silent push. It should be data only, any notification stuff in there will confound the test I think

In order to simplify how this stuff works I have a learned behavior now of _never_ sending notification information remotely. I always send data only ("silent push"), and use the handler to pop a locally crafted notification if that's what I want.

You're right!! :grinning:
Adding notification is just making things difficult. I only send data and the handler is called correctly. Thank you @mikehardy ;)

All 21 comments

Have you tried a test app made from the react-native-firebase template on react-native stable current (I think 0.61.3 as of just today, but maybe still 0.61.2). I don't think that would make a difference - you appear to have integrated correctly for pre-auto-linking react-native 0.59 but you never know

@Salakar @Ehesp I worked with @dorklord23 on Discord on this and I'm stumped personally.

@dorklord23 if at all possible you should use the firebase-admin module from the command line and send a push notification that you control. Without exposing your API key or a device token (of course), can you show the exact JSON you are attempting to push to the device via firebase? And can you examine unfiltered logcat with the device plugged in to see the relevant details there (in case there are any)?

@mikehardy I usually use Firebase Console to test notifications, though.
Interestingly, I have used adb logcat -s RNFirebaseMsgService:V to peek at the log and it showed nothing when a notification arrived while the app was in background even though I have added a few logs in ReactNativeFirebaseMessagingService.java like so:

Click To Expand

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.d(TAG, "onMessageReceived");
        ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance();

        // ----------------------
        // NOTIFICATION Message
        // --------------------\/
        // with no data
        if (remoteMessage.getNotification() != null && remoteMessage.getData().size() == 0) {
            Log.d(TAG, "TODO");
            // TODO broadcast intent when notifications module ready
            return;
        }

        // ----------------------
        // DATA Message
        // --------------------\/

        // |-> ---------------------
        // App in Foreground
        // ------------------------
        if (SharedUtils.isAppInForeground(getApplicationContext())) {
            Log.d(TAG, "onForeground");
            emitter.sendEvent(ReactNativeFirebaseMessagingSerializer.remoteMessageToEvent(remoteMessage));
            return;
        }

        // |-> ---------------------
        // App in Background/Quit
        // ------------------------
        try {
            Log.d(TAG, "in background");
            Intent intent = new Intent(getApplicationContext(), ReactNativeFirebaseMessagingHeadlessService.class);
            intent.putExtra("message", remoteMessage);
            ComponentName name = getApplicationContext().startService(intent);
            if (name != null) {
                Log.d(TAG, "waking the dragon");
                HeadlessJsTaskService.acquireWakeLockNow(getApplicationContext());
            }
        } catch (IllegalStateException ex) {
            Log.e(TAG, "Background messages only work if the message priority is set to 'high'", ex);
        }
    }


The log was like so:

10-30 00:29:16.141 26487 27890 D RNFirebaseMsgService: onMessageReceived
10-30 00:29:16.145 26487 27890 D RNFirebaseMsgService: onForeground

There should've been in background and waking the dragon in the log but alas there was none.

You will not be able to send silent pushes using the console. It just doesn't work for this purpose.

For full control you have to use the command line to test I think. I use something like this:

#!/bin/bash

DEV_SERVER_KEY="put your big old server key from firebase console here"

SERVER_KEY=$DEV_SERVER_KEY
#SERVER_KEY=$TEST_SERVER_KEY

curl -X POST \
--header "Authorization: key=$SERVER_KEY"  \
--Header "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d
 "{\"to\":\"/topics/AppInfo\",\"collapse_key\": \"AppInfo\",\"content_available\
": true, \"priority\": \"high\", \"data\":{\"IconCheck\":\"Testing Icon\"}}"

(note that specific payload may or may not work for you - it's a mish-mash of different things)

Oh, and run the logcat unfiltered. The play services things log under their own tags and processes etc

The fact that Log.d(TAG, "onForeground"); is being logged indicates your app is in the foreground / currently visible? setBackgroundMessageHandler is only for messages received while your app is closed / not active in the foreground, whilst onMessage should be used for when your app is in the foreground.

The isAppInForeground utility is identical to the one used in v5 so there should be no difference down to this util.

The fact that Log.d(TAG, "onForeground"); is being logged indicates your app is in the foreground / currently visible? setBackgroundMessageHandler is only for messages received while your app is closed / not active in the foreground, whilst onMessage should be used for when your app is in the foreground.

The isAppInForeground utility is identical to the one used in v5 so there should be no difference down to this util.

My bad. I was sending two notifications. The first one was when the app was in foreground (it was logged). The second one (the one that wasn't logged) was when the app is in background. It was quite late at night when I opened this issue.

@dorklord23 if at all possible you should use the firebase-admin module from the command line and send a push notification that you control. Without exposing your API key or a device token (of course), can you show the exact JSON you are attempting to push to the device via firebase? And can you examine unfiltered logcat with the device plugged in to see the relevant details there (in case there are any)?

This is my JSON:

POST https://fcm.googleapis.com/v1/projects/my-project/messages:send

{
    "validate_only": false,
    "message": {
        "name": "XXX",
        "data": {
            "title": "judul data",
            "message": "pesan data"
        },
        "notification": {
            "title": "judul notifikasi",
            "body": "isi notifikasi"
        },
        "topic": "C3166"
    }
}

The unfiltered log is overwhelming. I'll let you know if I find anything interesting.

@Salakar @mikehardy I have sent a few notifications while the app was in background. All of them were received but nothing is logged. There should have been a minimum of onMessageReceived in the log but nothing whatsoever even though I put it in the first line of onMessageReceived().

@Salakar @mikehardy I have sent a few notifications while the app was in background. All of them were received but nothing is logged. There should have been a minimum of onMessageReceived in the log but nothing whatsoever even though I put it in the first line of onMessageReceived().

onMessageReceived is for foreground messages, e.g. while your app is active, not backgrounded

@Salakar @mikehardy I have sent a few notifications while the app was in background. All of them were received but nothing is logged. There should have been a minimum of onMessageReceived in the log but nothing whatsoever even though I put it in the first line of onMessageReceived().

onMessageReceived is for foreground messages, e.g. while your app is active, not backgrounded

Then why is this piece of code inside of onMessageReceived? I presumed it is to start the headless task when the app is on background.

try {
    Intent intent = new Intent(getApplicationContext(), ReactNativeFirebaseMessagingHeadlessService.class);
    intent.putExtra("message", remoteMessage);
    ComponentName name = getApplicationContext().startService(intent);
    if (name != null) {
        HeadlessJsTaskService.acquireWakeLockNow(getApplicationContext());
    }
} catch (IllegalStateException ex) {
    Log.e(TAG, "Background messages only work if the message priority is set to 'high'", ex);
}

Have you tried a test app made from the react-native-firebase template on react-native stable current (I think 0.61.3 as of just today, but maybe still 0.61.2). I don't think that would make a difference - you appear to have integrated correctly for pre-auto-linking react-native 0.59 but you never know

@Salakar @Ehesp I worked with @dorklord23 on Discord on this and I'm stumped personally.

I have made another app with the template and it's exactly the same case :disappointed:

Your example JSON is not a silent push. It should be data only, any notification stuff in there will confound the test I think

In order to simplify how this stuff works I have a learned behavior now of never sending notification information remotely. I always send data only ("silent push"), and use the handler to pop a locally crafted notification if that's what I want.

Your example JSON is not a silent push. It should be data only, any notification stuff in there will confound the test I think

In order to simplify how this stuff works I have a learned behavior now of _never_ sending notification information remotely. I always send data only ("silent push"), and use the handler to pop a locally crafted notification if that's what I want.

You're right!! :grinning:
Adding notification is just making things difficult. I only send data and the handler is called correctly. Thank you @mikehardy ;)

I'm glad you got it working! This cements two things in my mind:

  • my rule of separating messaging from notifications is even more strictly enforced now
  • supporting messaging and notifications is nearly impossible. This stuff is so hard to get right

Good luck :-)

also that's the reason for testing with a script - it is literally impossible (at least as of this writing) to message data-only from the console. No idea why since it's so important, but there it is

"react-native": "0.61.3", I tried it on android, onMessage, setBackgroundMessageHandler
Good for you.
聽I will use it well, thank you

Hello,
First, thanks for this topic which helps me on my first ReactNative application.
With react-native-firebase v6, I get Message when app is Backgrounded & Foregrounded. But I don't know how to know in my app when user come from notification tap/click. I would like to redirect user on suitable view.

@seb-montana - RNFBv6 does not handle notification-anything. If you are sending mixed payloads from firebase cloud messaging (a cloud message with notification content and data content) then in the background the native firebase sdks will actually pop a notification for you, but react-native-firebase is not listening for the clicks or anything from the local notification APIs. You'll want to integrate react-native-push-notifications or similar and use their onNotification handler/listeners for that

Thanks you @mikehardy it's clear.. I've tried react-native-push-notifications yesterday and it's ok.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Draccan picture Draccan  路  3Comments

ODelibalta picture ODelibalta  路  3Comments

mahyarr picture mahyarr  路  3Comments

callmejm picture callmejm  路  3Comments

escobar5 picture escobar5  路  3Comments