React-native-firebase: :fire: Badge counter does not work

Created on 4 Mar 2019  路  11Comments  路  Source: invertase/react-native-firebase

Issue

Im able to fully receive and show notifications on iOS, but I'm not able to show a reliable badge counter.
What im trying to do is simple:

  • Receive notification --> increase badge by 1

In React we register to firebase stuff asap with this method:

firebase.notifications().onNotificationDisplayed((notification: Notification) => {
       firebase.notifications().getBadge()
          .then( count => {
            count++
            firebase.notifications().setBadge(count)
         })
         .then(() => {
           console.log('Doing great')
         })
         .catch( error => {
           console.log('fail to count')
         })
    });

onNotificationDisplayed because I want this to work in the background/while killed as well. If I use onNotification, the badge sometimes gets increased twice.

Which works the first boot and while app stays in memory. Both in foreground and background.
HOWEVER!
When the app is killed (first time since initial boot) the callback breaks. Restarting the app does not help and the badge is not incremented anymore.

Bonus issue

I found out that while incrementing the badge counter through code, the library/firebase/witches override the change. I see the counter being incremented and immediately reset to its previous value.
If I use a Math.random() to set the coutner in code I see the random value being set, and immedtiately back to its previous value. It seems like firebase remembers its last "badge":<value> thats beint sent with firebase. When not providing the badge field in the notification, it keeps restoring the last set value that was set through a notification

Notification format used to replicate the issue

{
  "to" : "%TO%",
  "priority": "high",
  "content_available": true,
  "notification" : {
    "body" : "noti body",
    "title" : "noti title",
    "link": "noti link ",
    <Optional>"badge": 4 <-- Badge is always sets to the last value you put in here if you let it out for some reason
  }
}

Project Files

iOS

ios/Podfile:

  • [ ] I'm not using Pods
  • [x] I'm using Pods

AppDelegate.m:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
    [[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}

Environment

  • Platform that you're experiencing the issue on:

    • [X] iOS

  • If known, the version of the platform are you experiencing the issue on:

    • iOS 11 e.g. iOS 10 or Android API 28

  • Build Tools:

    • Xcrash 10.1

  • React Native version:

    • 0.57.8

  • React Native Firebase library version:

    • 5.2.2

  • Firebase module(s) you're using that has the issue:

    • [X] Notifications

  • Are you using TypeScript?

    • [X] no

  • Are you using Expo, e.g. ExpoKit?

    • [x] no

  • Do you think this template should be cleaned up?

    - [x] yes

Notifications Stale 5.x.x

Most helpful comment

^ Nevermind, calling firebase.messaging().requestPermission() made it work (iOS only).

All 11 comments

See discussion here #2076 - not sure if Android badging is ever going to work well

I鈥檓 also not able to get badges to work on either iOS nor Android.

I call firebase.notifications().setBadge(5) and nothing happens, not even an error at the console.

react-native v0.59.8
react-native-firebase v5.5.4

I also tried enabling the Push Notifications capabilities (although the docs don鈥檛 mention it) but no success:

image

See Podfile

platform :ios, '9.0'

target 'devhub' do
  pod 'Firebase/Analytics'
  pod 'Firebase/Core'
  pod 'Firebase/Messaging'
  pod 'GoogleIDFASupport'
end

See Podfile.lock

PODS:
  - Firebase/Analytics (6.3.0):
    - Firebase/Core
  - Firebase/Core (6.3.0):
    - Firebase/CoreOnly
    - FirebaseAnalytics (= 6.0.2)
  - Firebase/CoreOnly (6.3.0):
    - FirebaseCore (= 6.0.3)
  - Firebase/Messaging (6.3.0):
    - Firebase/CoreOnly
    - FirebaseMessaging (~> 4.1.0)
  - FirebaseAnalytics (6.0.2):
    - FirebaseCore (~> 6.0)
    - FirebaseInstanceID (~> 4.2)
    - GoogleAppMeasurement (= 6.0.2)
    - GoogleUtilities/AppDelegateSwizzler (~> 6.0)
    - GoogleUtilities/MethodSwizzler (~> 6.0)
    - GoogleUtilities/Network (~> 6.0)
    - "GoogleUtilities/NSData+zlib (~> 6.0)"
    - nanopb (~> 0.3)
  - FirebaseAnalyticsInterop (1.2.0)
  - FirebaseCore (6.0.3):
    - GoogleUtilities/Environment (~> 6.0)
    - GoogleUtilities/Logger (~> 6.0)
  - FirebaseInstanceID (4.2.0):
    - FirebaseCore (~> 6.0)
    - GoogleUtilities/Environment (~> 6.0)
    - GoogleUtilities/UserDefaults (~> 6.0)
  - FirebaseMessaging (4.1.0):
    - FirebaseAnalyticsInterop (~> 1.1)
    - FirebaseCore (~> 6.0)
    - FirebaseInstanceID (~> 4.1)
    - GoogleUtilities/AppDelegateSwizzler (~> 6.2)
    - GoogleUtilities/Environment (~> 6.2)
    - GoogleUtilities/Reachability (~> 6.2)
    - GoogleUtilities/UserDefaults (~> 6.2)
    - Protobuf (~> 3.1)
  - GoogleAppMeasurement (6.0.2):
    - GoogleUtilities/AppDelegateSwizzler (~> 6.0)
    - GoogleUtilities/MethodSwizzler (~> 6.0)
    - GoogleUtilities/Network (~> 6.0)
    - "GoogleUtilities/NSData+zlib (~> 6.0)"
    - nanopb (~> 0.3)
  - GoogleIDFASupport (3.14.0)
  - GoogleUtilities/AppDelegateSwizzler (6.2.1):
    - GoogleUtilities/Environment
    - GoogleUtilities/Logger
    - GoogleUtilities/Network
  - GoogleUtilities/Environment (6.2.1)
  - GoogleUtilities/Logger (6.2.1):
    - GoogleUtilities/Environment
  - GoogleUtilities/MethodSwizzler (6.2.1):
    - GoogleUtilities/Logger
  - GoogleUtilities/Network (6.2.1):
    - GoogleUtilities/Logger
    - "GoogleUtilities/NSData+zlib"
    - GoogleUtilities/Reachability
  - "GoogleUtilities/NSData+zlib (6.2.1)"
  - GoogleUtilities/Reachability (6.2.1):
    - GoogleUtilities/Logger
  - GoogleUtilities/UserDefaults (6.2.1):
    - GoogleUtilities/Logger
  - nanopb (0.3.901):
    - nanopb/decode (= 0.3.901)
    - nanopb/encode (= 0.3.901)
  - nanopb/decode (0.3.901)
  - nanopb/encode (0.3.901)
  - Protobuf (3.8.0)

DEPENDENCIES:
  - Firebase/Analytics
  - Firebase/Core
  - Firebase/Messaging
  - GoogleIDFASupport

SPEC REPOS:
  https://github.com/cocoapods/specs.git:
    - Firebase
    - FirebaseAnalytics
    - FirebaseAnalyticsInterop
    - FirebaseCore
    - FirebaseInstanceID
    - FirebaseMessaging
    - GoogleAppMeasurement
    - GoogleIDFASupport
    - GoogleUtilities
    - nanopb
    - Protobuf

SPEC CHECKSUMS:
  Firebase: 8432d732974498afd5987e9001a05f90f1a3d625
  FirebaseAnalytics: 470ddab7253b21ad5a40bebd4a9903d7ae19386a
  FirebaseAnalyticsInterop: efbe45c8385ec626e29f9525e5ebd38520dfb6c1
  FirebaseCore: 68f8a7f50cdae542715d4e86afa37c4067217dcb
  FirebaseInstanceID: f20243a1d828e0e9a3798b995174dedc16f1b32a
  FirebaseMessaging: 0ac5310133e6ada4cdd44d42e92038855214a5e9
  GoogleAppMeasurement: a35a645835bae31b6bdc0576396bc23908f12a22
  GoogleIDFASupport: aaf8c10bd429abb1c15349d5252244f5eda8ead1
  GoogleUtilities: c7a0b08bda3bf808be823ed151f0e28ac6866e71
  nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48
  Protobuf: 3f617b9a6e73605565086864c9bc26b2bf2dd5a3

PODFILE CHECKSUM: 0b8014ee0d5bf90230a6ccd9aed82721393a6f21

COCOAPODS: 1.7.3

See AppDelegate.m

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#import "AppDelegate.h"

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

#import "RNSplashScreen.h"

#import <Firebase.h>
#import "RNFirebaseNotifications.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:@"devhub"
                                            initialProperties:nil];

  // #1F2229 (dark-gray)
  rootView.backgroundColor = [UIColor colorWithRed:0.12 green:0.13 blue:0.16 alpha:1.0];

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

  [FIRApp configure];
  [RNFirebaseNotifications configure];

  [RNSplashScreen show];

  return YES;
}

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

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
  return [RCTLinkingManager application:application openURL:url
                      sourceApplication:sourceApplication annotation:annotation];
}

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
  [[RNFirebaseNotifications instance] didReceiveLocalNotification:notification];
}

@end

The only logs about notifications on Xcode seems to be this:

2019-07-02 15:34:14.994123-0300 devhub[63794:1841982] -[RNFirebaseNotifications init] [Line 46] Setting up RNFirebaseNotifications instance
2019-07-02 15:34:15.217404-0300 devhub[63794:1841982] -[RNFirebaseNotifications init] [Line 46] Setting up RNFirebaseNotifications instance
2019-07-02 15:34:16.092975-0300 devhub[63794:1842100] 6.3.0 - [Firebase/Messaging][I-FCM001000] FIRMessaging Remote Notifications proxy enabled, will swizzle remote notification receiver handlers. If you'd prefer to manually integrate Firebase Messaging, add "FirebaseAppDelegateProxyEnabled" to your Info.plist, and set it to NO.

^ Nevermind, calling firebase.messaging().requestPermission() made it work (iOS only).

Hello,

I'm still not able to increment my badge value from mobile side when the app is killed, on IOS. It works on foreground. I only need to increment my value by +1 everytime i receive a remote notification. I never go in my listener (onNotification) when app is closed. Is this even possible with react-native-firebase ? Is there any way to do it natively ?

I have been stuck with this problem for weeks now. I've searched on every sources i could find, still no results.

Thanks a lot for your help

You might check the PRs, there鈥檚 one for iOS that allows for native handling of messages, with some commentary about how the app can鈥檛 successfully wake up completely to react-native javascript control flow because of iOS background processing limits. Maybe it is related?

@brunolemos interesting !!! can you show the code which you used to set badge

Closing this issue after a prolonged period of inactivity. If this is still present in the latest release, please feel free to create a new issue with up-to-date information.

I cannot find any setBadge or getBadge method. When I receive a notif, there is no badge on the app icon.

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

Badging for iOS is part of local device notification functionality, you'll need a package that handles local device notification APIs in order to handle it I think. For Android it is possible on some devices but runs contrary to the platform UI advice and is in general not recommended

Dear @mikehardy
Can I use this for ios? Is it comparable with the react native firebase cloud messaging (notification) ?

@ghasemikasra39 the very short answer is I think you can do what you want with that package

But I will be very very clear that you must separate the idea of "cloud messaging" (JSON packets going from the cloud to a device) and "notifications" (things a user can see, APIs on the local device to interact with them etc)

It is true that most cloud messaging libraries contain some code to handle local notifications - even react-native-firebase/messaging v6+ does, and the underlying messaging library will do some local notification stuff, but it is only for the most basic use cases.

So the combo of a messaging package and a full featured notification package integrated in your project is the goal. react-native-push-notification can handle both parts depending on your use case. Or you can combine react-native-firebase (for messaging) + react-native-push-notification just for notification API access. Or you can do react-native-firebase/messaging + notifee or react-native-notifications. Lots of options but keep it clear in your mind which part is doing what for when you need help with integration etc

Was this page helpful?
0 / 5 - 0 ratings