Skip to content

push notification app badges in v6.x #3419

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
6 of 10 tasks
wzhang2 opened this issue Apr 8, 2020 · 41 comments
Closed
6 of 10 tasks

push notification app badges in v6.x #3419

wzhang2 opened this issue Apr 8, 2020 · 41 comments

Comments

@wzhang2
Copy link

wzhang2 commented Apr 8, 2020

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’s worth, i’m sending messages to a firebase topic and i’m subscribing to that topic upon app launch, and i’m 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
  • 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?

  • 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:

// 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:
    • iOS
    • 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:
    • e.g. 6.4.0
  • Firebase module(s) you're using that has the issue:
    • app, messaging
  • Are you using TypeScript?
    • N & VERSION


@wzhang2 wzhang2 changed the title push notification app badges push notification app badges in v6.x Apr 8, 2020
@boreales
Copy link

boreales commented Apr 8, 2020

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.

@wzhang2
Copy link
Author

wzhang2 commented Apr 8, 2020

@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"
}

@wzhang2
Copy link
Author

wzhang2 commented Apr 8, 2020

@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

@wzhang2
Copy link
Author

wzhang2 commented Apr 8, 2020

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

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

@boreales
Copy link

boreales commented Apr 8, 2020

@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.

@boreales
Copy link

boreales commented Apr 8, 2020

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.

@enigmasteron
Copy link

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

@wzhang2
Copy link
Author

wzhang2 commented Apr 8, 2020

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

@Ehesp
Copy link
Member

Ehesp commented Apr 8, 2020

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?

@wzhang2
Copy link
Author

wzhang2 commented Apr 8, 2020

@Ehesp thanks, and yes i tried that and it works, but please correct me if i’m 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’t really wanna downgrade to v5 since that’s deprecated

@Ehesp
Copy link
Member

Ehesp commented Apr 8, 2020

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.

@wzhang2
Copy link
Author

wzhang2 commented Apr 8, 2020

@Ehesp thanks. i shall try that

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

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

if that’s 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’t want to set the ios count from the sender every time

@Ehesp
Copy link
Member

Ehesp commented Apr 8, 2020

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?

@Salakar
Copy link
Contributor

Salakar commented Apr 8, 2020

@Ehesp
Copy link
Member

Ehesp commented Apr 8, 2020

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

@wzhang2
Copy link
Author

wzhang2 commented Apr 9, 2020

@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?

@wzhang2
Copy link
Author

wzhang2 commented Apr 9, 2020

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

@changLiuUNSW
Copy link

changLiuUNSW commented Apr 14, 2020

@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

@wzhang2
Copy link
Author

wzhang2 commented Apr 14, 2020

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

@changLiuUNSW
Copy link

@wzhang2 Do u find any library for Android ?

@nabilfreeman
Copy link

nabilfreeman commented Apr 16, 2020

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

@skizzo
Copy link

skizzo commented Apr 18, 2020

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..

@mikehardy
Copy link
Collaborator

@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

@salehshah
Copy link

salehshah commented Apr 21, 2020

it was some cache, i got this to work finally when i loaded the device using xcode, but it still doesn’t 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?

@thecodecafe
Copy link

@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

@ghasemikasra39
Copy link

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",

@skizzo
Copy link

skizzo commented Jul 9, 2020

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.

@ahanusek
Copy link

ahanusek commented Jul 9, 2020

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.

@mikehardy
Copy link
Collaborator

@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...

@skizzo
Copy link

skizzo commented Jul 10, 2020

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

@guhcostan-equals
Copy link

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

Some solution?

@mikehardy
Copy link
Collaborator

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

@guhcostan-equals
Copy link

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.

@jonra1993
Copy link

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??

@CaptainJeff
Copy link

@jonra1993 I have this issue as well

@Biplovkumar
Copy link

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
Copy link

@jonra1993 I have this issue as well

Hi @CaptainJeff have you found any solution.

@ArnasJack
Copy link

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.

@CaptainJeff
Copy link

@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)

@mikehardy
Copy link
Collaborator

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 😅

@CVRamana
Copy link

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.

did u mean::
await messaging().requestPermission({
sound: false,
announcement: true,
// ... other permission settings
});
in firebase

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests