React-native-firebase: push notification app badges in v6.x

Created on 8 Apr 2020  路  40Comments  路  Source: invertase/react-native-firebase


Issue



Describe your issue here

does anyone know how I can make the app badges show up when i receive push notifications? is this something I will need to handle myself? cause I saw that you could handle it with firebase.notification in 5.x versions.

I see that the badge does show up on androids, but its not going away even after I open the app, is this also something that i will need to handle myself?

banner and sound work, just not the badges

for what it鈥檚 worth, i鈥檓 sending messages to a firebase topic and i鈥檓 subscribing to that topic upon app launch, and i鈥檓 testing this via testflight and side load apk

I can set the badge from the server, but I think that should be handled from the client

thanks so much

Project Files






Javascript

import messaging from '@react-native-firebase/messaging';

async checkPermission() {
        const authStatus = await messaging().hasPermission();
        if (messaging.AuthorizationStatus.AUTHORIZED === authStatus) {
            this.getToken();
        } else {
            this.requestPermission();
        }
    }

    async requestPermission() {
        try {
            await messaging().requestPermission();
            // User has authorised
            if (!messaging().isDeviceRegisteredForRemoteMessages) {
                await messaging().registerDeviceForRemoteMessages();
            }
            this.getToken();
        } catch (error) {
            // User has rejected permissions
            console.log('permission rejected');
        }
    }

    async getToken() {
        let fcmToken = await AsyncStorage.getItem('fcmToken');
        if (!fcmToken) {
            fcmToken = await messaging().getToken();
            if (fcmToken) {
                await AsyncStorage.setItem('fcmToken', fcmToken);
            }
        }
    }

package.json:

{
  "name": "name",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "@react-native-community/async-storage": "^1.6.1",
    "@react-native-firebase/app": "^6.4.0",
    "@react-native-firebase/messaging": "^6.4.0",
    "jwt-decode": "^2.2.0",
    "moment": "^2.24.0",
    "react": "16.9.0",
    "react-native": "0.60.5",
    "react-native-chart-kit": "^3.6.1",
    "react-native-device-info": "^4.0.1",
    "react-native-elements": "^1.1.0",
    "react-native-gesture-handler": "^1.4.1",
    "react-native-linear-gradient": "^2.5.6",
    "react-native-reanimated": "^1.2.0",
    "react-native-screens": "^1.0.0-alpha.23",
    "react-native-svg": "^9.8.4",
    "react-native-vector-icons": "^6.6.0",
    "react-native-webview": "^7.0.2",
    "react-navigation": "^4.0.0",
    "react-navigation-drawer": "^2.2.1",
    "react-navigation-stack": "^1.5.1",
    "react-navigation-tabs": "^2.4.0",
    "react-redux": "^7.1.1",
    "redux": "^4.0.4",
    "redux-logger": "^3.0.6",
    "redux-thunk": "^2.3.0"
  },
  "devDependencies": {
    "@babel/core": "7.5.5",
    "@babel/runtime": "7.5.5",
    "@react-native-community/eslint-config": "0.0.3",
    "babel-jest": "24.9.0",
    "eslint": "6.3.0",
    "jest": "24.9.0",
    "metro-react-native-babel-preset": "0.54.1",
    "react-test-renderer": "16.8.6"
  },
  "jest": {
    "preset": "react-native",
    "setupFiles": [
      "./node_modules/react-native-gesture-handler/jestSetup.js"
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!react-native|react-navigation)/"
    ]
  }
}

firebase.json for react-native-firebase v6:

# N/A

iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: platform :ios, '9.0' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' target 'App' do # Pods for App pod 'React', :path => '../node_modules/react-native/' pod 'React-Core', :path => '../node_modules/react-native/React' pod 'React-DevSupport', :path => '../node_modules/react-native/React' pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket' pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga' pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' pod 'react-native-webview', :path => '../node_modules/react-native-webview' pod 'RNReanimated', :path => '../node_modules/react-native-reanimated' pod 'RNGestureHandler', :path => '../node_modules/react-native-gesture-handler' pod 'RNDeviceInfo', :path => '../node_modules/react-native-device-info' pod 'RNFBApp', :path => '../node_modules/@react-native-firebase/app' pod 'RNFBMessaging', :path => '../node_modules/@react-native-firebase/messaging' target 'AppTests' do inherit! :search_paths # Pods for testing end use_native_modules! end

# N/A
#### `AppDelegate.m`:
#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <Firebase.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"App"
                                            initialProperties:nil];

  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];

  if ([FIRApp defaultApp] == nil) {
    [FIRApp configure];
  }
  return YES;
}

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

@end


Android

Click To Expand

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

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

buildscript {
    ext {
        buildToolsVersion = "28.0.3"
        minSdkVersion = 19
        compileSdkVersion = 28
        targetSdkVersion = 28
        supportLibVersion = "28.0.0"
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath('com.android.tools.build:gradle:3.5.0')
        classpath 'com.google.gms:google-services:4.3.3'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

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()
    }
}

#### `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",
 *
 *   // https://facebook.github.io/react-native/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 = [
    entryFile: "index.js",
    enableHermes: false,  // 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", false);

android {
    compileSdkVersion rootProject.ext.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        applicationId "com.company.name"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0.1"
    }

    lintOptions {
        checkReleaseBuilds true
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }

     signingConfigs {
        release {
            if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
                storeFile file(MYAPP_UPLOAD_STORE_FILE)
                storePassword MYAPP_UPLOAD_STORE_PASSWORD
                keyAlias MYAPP_UPLOAD_KEY_ALIAS
                keyPassword MYAPP_UPLOAD_KEY_PASSWORD
            }
        }
    }

    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
        }
    }
    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        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"
        }
    }
    // 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 project(':@react-native-firebase_messaging')
    implementation project(':@react-native-firebase_app')
    implementation project(':react-native-device-info')
    implementation project(':react-native-webview')
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.facebook.react:react-native:+"  // From node_modules
    implementation "com.google.android.gms:play-services-base:17.2.1"
    implementation "com.google.firebase:firebase-core:17.3.0"

   if (enableHermes) {
      def hermesPath = "../../node_modules/hermesvm/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'
}
project.ext.vectoricons = [
    iconFontNames: [ 'icomoon.ttf', 'EvilIcons.ttf' ] // Name of the font files you want to copy
]
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
apply plugin: 'com.google.gms.google-services'
#### `android/settings.gradle`:
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-device-info'
project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
include ':react-native-gesture-handler'
project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-gesture-handler/android')
include ':react-native-reanimated'
project(':react-native-reanimated').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-reanimated/android')
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
include ':@react-native-firebase_messaging'
project(':@react-native-firebase_messaging').projectDir = new File(rootProject.projectDir, './../node_modules/@react-native-firebase/messaging/android')
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
#### `MainApplication.java`:
import android.app.Application;

import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {

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

    @Override
    protected List<ReactPackage> getPackages() {
      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();
    SoLoader.init(this, /* native exopackage */ false);
  }
}
#### `AndroidManifest.xml`:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
  package="com.company.name">

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

  <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize"
        android:screenOrientation="portrait">
        <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" />
      <service android:name="io.invertase.firebase.messaging.ReactNativeFirebaseMessagingService">
          <intent-filter>
              <action android:name="com.google.firebase.MESSAGING_EVENT" />
          </intent-filter>
      </service>
      <meta-data
          android:name="com.google.firebase.messaging.default_notification_icon"
          android:resource="@drawable/ic_notification" />
      <meta-data
          tools:replace="android:resource"
          android:name="com.google.firebase.messaging.default_notification_color"
          android:resource="@color/notificationAccent" />
  </application>

</manifest>


Environment

Click To Expand

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

System:
    OS: macOS 10.15.1
    CPU: (4) x64 Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz
    Memory: 765.46 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.9.1 - /usr/local/bin/node
    npm: 6.10.3 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 23, 25, 26, 27, 28, 29
      Build Tools: 23.0.1, 25.0.1, 26.0.2, 27.0.3, 28.0.3, 29.0.0, 29.0.2
      System Images: android-29 | Google Play Intel x86 Atom
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5791312
    Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
  npmPackages:
    react: 16.9.0 => 16.9.0 
    react-native: 0.60.5 => 0.60.5 
  npmGlobalPackages:
    create-react-native-app: 1.0.0
    react-native-cli: 2.0.1
- **Platform that you're experiencing the issue on**: - [X] iOS - [X] Android - [ ] **iOS** but have not tested behavior on Android - [ ] **Android** but have not tested behavior on iOS - [X] Both - **`react-native-firebase` version you're using that has this issue:** - `e.g. 6.4.0` - **`Firebase` module(s) you're using that has the issue:** - `app, messaging` - **Are you using `TypeScript`?** - `N` & `VERSION`




Most helpful comment

I worked around this by adding:

- (void)applicationDidBecomeActive:(UIApplication *)application {
  [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}

to AppDelegate.m.

This is the only thing I was using setBadgeCount for anyway. If you set a badge on the server-side message I think it increments the ios badge anyway

All 40 comments

I have the same problem.

Also, on iOS, badges doesn't appear and I have neither vibration/sound for notifications. Just the banner is displayed.

@boreales sound and vibration work for me, I assume you have set the sound in your notification payload?

{
    "to": "myToken",
    "notification": {
         "body": "test",
         "title": "test",
         "sound": "default"
    },
    "priority": "high"
}

@boreales sound and vibration work for me, I assume you have set the sound in your notification payload?

{
    "to": "myToken",
    "notification": {
         "body": "test",
         "title": "test",
         "sound": "default"
    },
    "priority": "high"
}

if I were to add "badge": "1" next to sound, then I will always see the badge showing up as 1...but that's not how I want to handle it, I want to handle it on the client side,

for my use case, when the app is in the background, the badge should add up every time a push is received, and when the app comes to the foreground, the badge should be cleared

is this something I would need to handle using firebase.messaging().onMessage and this library?

https://github.com/zo0r/react-native-push-notification

@boreales sound and vibration work for me, I assume you have set the sound in your notification payload?

{
    "to": "myToken",
    "notification": {
         "body": "test",
         "title": "test",
         "sound": "default"
    },
    "priority": "high"
}

Yes it works now with the sound param.
Anyway I still have no badge that appears.

is this something I would need to handle using firebase.messaging().onMessage and this library?

https://github.com/zo0r/react-native-push-notification

I don't think so. It's not the same library as Firebase.

Yeah agree, i also need methods for set and get badge counts. V6

I think in v5 this was handled with firebase.notifications, but seems like that's not in v6 yet according to #2566, and I guess the only other workarounds are

react-native-firebase v5
react-native-firebase v6 + react-native-push-notification (or other 3rd party) for free
react-native-firebase v6 + recently announced Invertase licensed product "Notifee" which is still in alpha

We haven't added this API because we see it as out of scope for messaging.

The Android implementation was a wrapper around ShortcutBadger which looks abandoned so we don't want to have to support an underlying library in that state, and also not many Android launchers actually support number badges these days.

Technically our API should support setting a badge count via an FCM payload as you can set it on the Firebase console (therefore via other custom methods):

image

Has anyone tried that value to see if it works on iOS?

@Ehesp thanks, and yes i tried that and it works, but please correct me if i鈥檓 wrong, does that mean the server sending out these messages would need to keep track of the message count for every client? what if i want the message count to zero out when the user launches the app?

if i were to keep track of that in the client, i would probably need to create a special notification to alter that every time the app receives a push or comes back to foreground?

to achieve what i wanna do here, is it better for me to integrate with another third party library like react-native-push-notification and set this value in messaging().onMessage()?

i don鈥檛 really wanna downgrade to v5 since that鈥檚 deprecated

iOS only supports setting a value, rather than incrementing a value. Assuming you have the API to handle getting/setting badge values, you could do this within the background handler:

messaging().setBackgroundMessageHandler(async remoteMessage => {
  await someLib.incrementBadgeCount();
});

When the app is open, you could then set the badge count to zero.

@ehesp thanks. i shall try that

just to clarify, is setBackgroundMessageHandler for android only as it indicates in the doc? and it鈥檚 a noop for ios

https://rnfirebase.io/reference/messaging#setBackgroundMessageHandler

if that鈥檚 the case, can you please let me know how i can handle that in ios? can i use onMessage for both platforms? if i don鈥檛 want to set the ios count from the sender every time

Ah that needs to be updated. It should work on iOS, just follow along here:

https://rnfirebase.io/messaging/usage#background--quit-state-messages

cc @Salakar do we pass the headless prop on to check whether it booted on iOS from background?

Yeah wow, I even wrote them docs and forgot haha.

@Ehesp thanks, I tried to set that in my index.js, however I'm not seeing anything in logcat besides this:

04-09 13:57:58.355 13465 13465 D RNFirebaseMsgReceiver: broadcast received for message
04-09 13:57:58.384 13465 13500 W ReactNativeJS: No background message handler has been set. Set a handler via the "setBackgroundMessageHandler" method.

here's my index.js

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

messaging().setBackgroundMessageHandler(async remoteMessage => {
    console.log('Message handled in the background!', remoteMessage);
});


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

here's how my App.js, the AppContainer is created with react-navigation:

import React from 'react';
import { SafeAreaView } from 'react-native';
import AppContainer from './src/AppContainer';
import configureStore from './src/store/configureStore';
import { Provider } from 'react-redux';
export const store = configureStore();

export default function App() {
  return (
    <SafeAreaView style={{flex: 1}}>
      <Provider store={store}>
        <AppContainer />
      </Provider>
    </SafeAreaView>
  );
}

is this only supposed to work with silent push?

it was some cache, i got this to work finally when i loaded the device using xcode, but it still doesn鈥檛 work when i archive it and download it via testflight

@Ehesp @wzhang2 I saw this ticket get closed but I still cant find setBadge available in the v6 yet ?
Can we reopen this issues otherwise we will lose track of those tickets which have been linked to this one

We haven't added this API because we see it as out of scope for messaging.

The Android implementation was a wrapper around ShortcutBadger which looks abandoned so we don't want to have to support an underlying library in that state, and also not many Android launchers actually support number badges these days.

Technically our API should support setting a badge count via an FCM payload as you can set it on the Firebase console (therefore via other custom methods):

image

Has anyone tried that value to see if it works on iOS?

@changLiuUNSW I believe @Ehesp mentioned that this feature is out of scope, so you will need to use some combination of other third party libraries to make that work

@wzhang2 Do u find any library for Android ?

I worked around this by adding:

- (void)applicationDidBecomeActive:(UIApplication *)application {
  [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}

to AppDelegate.m.

This is the only thing I was using setBadgeCount for anyway. If you set a badge on the server-side message I think it increments the ios badge anyway

Could somebody explain to me why this issue was closed? I just upgraded from v5.5.5 to v6.4.0 and this feature is missing, without a word about it in the new docs..

@skizzo I believe the fact RNFBv6 does not support local notification APIs and that in the conversion from RNFBv5 to v6 you need to find a helper library to handle the local notification APIs is documented

that is the reason

Firebase is a cloud service, messaging is a cloud thing and is supported, but notifications are local device APIs and are out of scope going forward

it was some cache, i got this to work finally when i loaded the device using xcode, but it still doesn鈥檛 work when i archive it and download it via testflight

@wzhang2 I am facing the same issue, setBackgroundMessageHandler in index.js is not called when the build mode is set to release. It works fine in debug mode. Were you able to find any solution?

@mikehardy I think what can help is for a suggested third-party library in the docs that can be used for such, @nabilfreeman solution for iOS works fine, what's left is android, looking at Shourtcut Badger but if it appears abandoned then I might be a bit sceptical using it, will try to test on android and see if it works fine though.

If you're looking for a way to reset badge at Launch you can use @nabilfreeman solution above for iOS, however, this does not reset the badge count if the app was not in quite-mode at the point of being launched.

As for Android, you can check out Shourtcut Badger, hope this helps.

@skizzo I believe the fact RNFBv6 does not support local notification APIs and that in the conversion from RNFBv5 to v6 you need to find a helper library to handle the local notification APIs is documented

that is the reason

Firebase is a cloud service, messaging is a cloud thing and is supported, but notifications are local device APIs and are out of scope going forward

I don't see any badge counter on my app icon. Any solution?

   "react-native": "0.62.2",
    "@react-native-firebase/app": "^7.1.0",
    "@react-native-firebase/messaging": "^7.1.1",

I don't see any badge counter on my app icon. Any solution?

   "react-native": "0.62.2",
    "@react-native-firebase/app": "^7.1.0",
    "@react-native-firebase/messaging": "^7.1.1",

there is none, which is why i went with version 5.x. quite the dealbreaker.

I don't see any badge counter on my app icon. Any solution?

   "react-native": "0.62.2",
    "@react-native-firebase/app": "^7.1.0",
    "@react-native-firebase/messaging": "^7.1.1",

Show payload of your notification which you send by using a Firebase admin API.

@skizzo this is a losing choice, you'll get zero maintenance. Integrate a full 3rd party local device notification library. There are many options, but the v5 notifications package was poorly supported (it's a massive API set and not part of firebase so did not see sufficient attention here) and v5 messaging had many issues with fixes in v6+ #3339 which you will want. Staying on v5 is something I would try to dissuade you from in the strongest terms. But of course, whatever works, it is open source...

@mikehardy you are obviously right, but as somebody who needs to update an app ASAP and can鈥榯 spend days on finding (and testing) a solution for something that was working before, this is the way to go for now.

Ios badge is not working for me, the notifications are shown but the badge doesn't increment.

Some solution?

If you want to control badging etc I think you will need a full-featured 3rd party local device notification package. There are at least 3 known working with react-native-firebase - notifee.app, react-native-push-notification, react-native-notifications

If you want to control badging etc I think you will need a full-featured 3rd party local device notification package. There are at least 3 known working with react-native-firebase - notifee.app, react-native-push-notification, react-native-notifications

Ahhhh, ok, thank you.

Hello, have any of you had an issue in which budget counter appears on an android device but they do not go to zero after opening, they just continue increasing??

@jonra1993 I have this issue as well

Hi @Ehesp @Salakar,

Info:-

"react": "16.13.1",
"react-native": "0.63.3",
"@react-native-firebase/app": "^8.4.5",

Code:-

firebase.notifications().setBadge(5);

Not working in IOS & Android too.
please open it OR Give solution of react-native.
I am stuck before 5 days.
please help.

@jonra1993 I have this issue as well

Hi @CaptainJeff have you found any solution.

When I had the same issue I found that I simply wasn't asking for the permission to show the badge, after I included that with other permissions everything worked fine.

@jonra1993

I didn't read @mikehardy's comments above close enough he mentioned that they separated the handling of notification receiving and handling. This project no longer "creates" notifications so we need a third party app. I"m using notifee.app and it works as expected (for ios)

await notifee.setBadgeCount(badge)

I am also very particular about terminology. react-native-firebase doesn't receive "notifications", it receives "firebase cloud messages" that contain "payloads", and it is possible that the payload may have a notification component, or just be data-only etc, but without being precise on those terms it's nearly impossible to troubleshoot the 200 ways it can fail because it's not clear exactly which part worked or did not work 馃槄

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alizahid picture alizahid  路  3Comments

callmejm picture callmejm  路  3Comments

dgruseck picture dgruseck  路  3Comments

csumrell picture csumrell  路  3Comments

joecaraccio picture joecaraccio  路  3Comments