Skip to content
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

[🐛] setBackgroundMessageHandler not working on ios #4705

Closed
mikeal222 opened this issue Dec 23, 2020 · 49 comments
Closed

[🐛] setBackgroundMessageHandler not working on ios #4705

mikeal222 opened this issue Dec 23, 2020 · 49 comments
Labels
help: needs-triage Issue needs additional investigation/triaging. type: bug New bug report

Comments

@mikeal222
Copy link

mikeal222 commented Dec 23, 2020

setBackgroundMessageHandler is not working in ios on android working fine.

Payload Admin :

const message = {
  token: 'token',
  notification: {
    body: 'This is an FCM notification that displays an image!',
    title: 'FCM Notification',
  },
  data: {
    user: 'user',
  },
  apns: {
    payload: {
      aps: {
        "content_available": true,
      },
      headers: {
        'apns-push-type': 'background',
        'apns-priority': '5',
      }
    },
    fcm_options: {
      image: 'image-url',
    },
  },
  android: {
    priority :'high',
    notification: {
      image: "image-url",
    },
  },
};


admin.messaging().send(message);

index.js

  messaging().setBackgroundMessageHandler(async remoteMessage => {
    console.log('Background!', remoteMessage);
  });
  
  function HeadlessCheck({ isHeadless }) {
    if (isHeadless) {
      // App has been launched in the background by iOS, ignore
      return null;
    }

    return <App />;
  }

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

ios podfile

Override Firebase SDK Version

$FirebaseSDKVersion = '7.0.0'

package.json

    "@react-native-firebase/app": "^8.4.7",
    "@react-native-firebase/auth": "^9.3.1",
    "@react-native-firebase/firestore": "^7.8.7",
    "@react-native-firebase/messaging": "^7.9.1",
@mikeal222 mikeal222 added help: needs-triage Issue needs additional investigation/triaging. type: bug New bug report labels Dec 23, 2020
@andersonaddo
Copy link
Contributor

Update to newest versions of our package, we're on v10+

Next time properly format your issue too.

This is a solved problem, lots of GitHub issues about it.
#4151 (comment)

@mikeal222
Copy link
Author

mikeal222 commented Dec 31, 2020

    "@react-native-firebase/analytics": "^10.4.0",
    "@react-native-firebase/app": "^10.4.0",
    "@react-native-firebase/auth": "^10.4.0",
    "@react-native-firebase/firestore": "^10.4.0",
    "@react-native-firebase/messaging": "^10.4.0",

and its still not working on ios background mode

@mikeal222
Copy link
Author

mikeal222 commented Dec 31, 2020

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 "RNFBMessagingModule.h"
#import <Firebase.h>
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <GoogleMaps/GoogleMaps.h>


@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  if ([FIRApp defaultApp] == nil) {
    [FIRApp configure];
  }
  [GMSServices provideAPIKey:@"KEY"];

NSDictionary *appProperties = [RNFBMessagingModule addCustomPropsToUserProps:nil withLaunchOptions:launchOptions];
  
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"App3"
                                            initialProperties:appProperties];

  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];
  return YES;
}



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

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


@end

@mikehardy
Copy link
Collaborator

It works for me, sorry. No idea what's wrong with your project. Maybe missing entitlements, maybe missing notification permission, maybe iOS is throttling you (you'll see messages in the console if you turn on firebase-ios-sdk debug flags in your build scheme and watch the console on a real device - #4603 (comment))

@mikeal222
Copy link
Author

mikeal222 commented Jan 3, 2021

Im receiving the onmessage push notification works fine console log dont shows any throttling.its just not getting any log on setbackgroundhandler

 messaging().setBackgroundMessageHandler(async remoteMessage => {
    console.log('Background!', remoteMessage);
  });

@mikehardy
Copy link
Collaborator

That usually means you set the background handler after registered the app component. Background handlers need to be set in index.js (or equivalent) prior to registering / rendering the app

I will be as clear as possible though: it works. It is one of the most important uses of react-native-firebase. Your problem will be resolved by some change to your project code, not the module - so keep looking and checking your code

@leurs247
Copy link

leurs247 commented Jan 4, 2021

I'm facing the same issue here.

My index.js-file looks like this:


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

const onMessageReceived = async (message) => {
  await notifee.displayNotification({
    title: message.data.title,
    body: message.data.body
  });
};

messaging().onMessage(onMessageReceived);

messaging().setBackgroundMessageHandler(onMessageReceived);

const HeadlessCheck = ({ isHeadless }) => {
  if (isHeadless) {
    return null;
  }

  return <App />;
};

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

Some other important things:

  • I have tested the iOS app both in debug scheme and release scheme
  • I'm receiving general notifications as expected (the problem lies with data-only messages)
  • The data-only message has the appropriate APN headers (like stated here)
  • When the app is open, it works: the notification is displayed by notifee. If the app is in background mode/closed, no notification pops up.
  • I have updated appdelegate.m (as stated here) to inject a isHeadless prop
  • device iOS is 14.2
  • I'm using a real device (not a simulator)

Edit:
I was playing around with firebase-admin (nodeJS). To have a (temporary) solution, I wanted to add the notification-object to the message object.

const token = '...';
const title = 'Hello world';
const body = 'It works!';
      admin.messaging().send({
        token,
        notification: {
          title,
          body
        },
        data: {
          title,
          body
        },
        apns: {
          payload: {
            aps: {
              contentAvailable: true
            }
          },
          headers: {
            'apns-push-type': 'background',
            'apns-priority': '5',
            'apns-topic': 'com.myapp.name'
          }
        },
      });

This does not work when the app is in background mode/closed. Even the notification itself is not displayed. When I remove the apns-object, it works! The message is triggered in foreground and in background mode.

Second edit:
Removing the header apns-push-typeseems to solve the issue mentioned in my first edit. Without this header, I receive the content of the notification-object when the app is closed, and it triggers notifee when the app is open (with the content in the data-object).

@leurs247
Copy link

leurs247 commented Feb 1, 2021

I'm still facing this issue.

I've added the -FIRAnalyticsDebugEnabled and -FIRMessagesDebugEnabled arguments to my xCode scheme. I'm watching the console (Window > Devices and Simulators > Open Console) to look for incoming messages, but I have no idea what to expect.

I'm also checking the xCode debug console.

I'm testing on an iPhone 6s (ios 14.1). When the app is open, all messages arrive, and they are pretty fast (like 1 second after I've triggered a remote notification through my server). The problem lies with setbackgroundmessagehandler(). Most of these notifications are not delivered at all (question: what do I need to look for in the console to see if it's really not delivered or if there is a problem in my code to show them?). Sometimes, one or two notifications do get delivered. But after those notifications, it stops working for like 10 minutes.

I can't image there is something wrong with my code because some messages do get delivered? I'm looking for apple's apn throttling, but isn't 2 notifications in 10 minutes not really, really bad?

@mikehardy
Copy link
Collaborator

If you say "most of these notifications are not delivered" that implies while in background some are delivered, no? If that is the case - some are delivered - then your code is fine. There would be zero delivery if your code was wrong.

If some are delivered you are being throttled. What to look for is some log entries showing the phone saw a message like this #4603 (comment) followed by nothing, which means your phone decided "for some reason this isn't important enough to boot the app and deliver it, which is fine by API design contract because data-only messages are not guaranteed delivery"

@rdsedmundo
Copy link

rdsedmundo commented May 23, 2021

I can't get setBackGroundMessageHandler to be called no matter what. I have revised my configuration entirely 3x with the Firebase documentation and everything is correct. It works on Android.

I open the app, minimize it, then I trigger a regular notification (not data-only). I get notified via push notification on my iPhone, but the handler is not called. I have my code also listening to onNotificationOpenedApp and after I click on the notification and the app is resumed I can see the remote message there perfectly, so I don't understand why the setBackgroundMessageHandler is not called as the message is being recognized.

I have tried both with the headless prop and without it, same results.

@mikehardy
Copy link
Collaborator

Please use precise terms, it's important, I will be pedantic about it.
You are sending "FCM".
"FCM" contain "payloads"
Your "payload" may contain "data", "notification" or both mixed as payload blocks.

Now let me restate what I read, but precisely:

You send an FCM with mixed payload. This will never trigger a background message handler, per the docs.

If you send an FCM with data-only payload (only achievable by FCM REST API, not the console) with the correct keys in the data payload (content-available needs to be there) and the phone is set up to allow it (background refresh on, not thermally throttled, not in low power mode, plenty of battery, you haven't used your power budget yet, etc etc) it will deliver.

This is subtle. But it's also all documented.

@rdsedmundo
Copy link

You're correct about all assumptions, I sent an FCM with a payload containing a notification and data in it.

You send an FCM with mixed payload. This will never trigger a background message handler, per the docs.

Where in the documentation is that stated? This is not what I understand reading this table. It clearly says that Notification + Data calls setBackgroundMessageHandler—and it is what I see in Android, but not on iOS, I can't find anywhere there saying that it's an exception.

Also here it says:

When the application is in a background or quit state, the onMessage handler will not be called when receiving messages. Instead, you need to setup a background callback handler via the setBackgroundMessageHandler method.

@mikehardy
Copy link
Collaborator

Mmm - that documentation may not be right, let me search upstream

It's my understanding that as soon you include a notification block in your payload you get nothing until the user interacts with the notifcation, at which point you get onMessage with data payload included, because at that point you are not in background, you've been brought to foreground.

Have you tested it? This should be what you experienced.

@mikehardy
Copy link
Collaborator

There is also a poorly-defined-on-that-page fourth state of "force closed" and some sub-states of "system throttled" (e.g. https://dontkillmyapp.com or all the power-miser algorithm throttling Apple will do to you, or background refresh is off) the page could use some work

@mikehardy
Copy link
Collaborator

https://firebase.google.com/docs/cloud-messaging/concept-options#notification-messages-with-optional-data-payload

@babyrusa
Copy link

@rdsedmundo Hi did you ever get this to work. It's happening to me and I've been googling to find a solution. I've tried headless and without as well. I add code in AppDelegate file as well. I'm not sure what I missed. Can someone assist? @mikehardy

@rdsedmundo
Copy link

No, I still couldn't make it to work via the setBackgroundMessageHandler anyhow.

It's my understanding that as soon you include a notification block in your payload you get nothing until the user interacts with the notifcation, at which point you get onMessage with data payload included, because at that point you are not in background, you've been brought to foreground.
Have you tested it? This should be what you experienced.

Because I'm sending a full notification and not data-only if the user clicks the notification I can get the data using onNotificationOpenedApp, but setBackgroundMessageHandler is still not called. I'll do more tests using data-only to see if it helps.

Do you know of any tricks to avoid the Apple throlling while in development? For example, reinstalling the app completely?

@mikehardy
Copy link
Collaborator

Full battery full power making sure device is not too hot make sure background refresh is on and low power mode is off - those are all the tricks I know.

@mikehardy
Copy link
Collaborator

you will not get a background message handler called ever if you send a notification block. You'll get either a notification open, or an onmessage with data in there, but it's never background if a user tapped on your notification so that hook does not apply

@babyrusa
Copy link

I'm in the same situation where I have both 'notification' and 'data' in the payload
I don't use react-native-push-notification or react-native-push-notification-ios, does that matter? Because I don't need notifications to show when the user is in the app

@rdsedmundo
Copy link

you will not get a background message handler called ever if you send a notification block. You'll get either a notification open, or an onmessage with data in there, but it's never background if a user tapped on your notification so that hook does not apply

I see, but this works on Android for what it's worth: data+notification calls setBackgroundMessageHandler. I realize though that iOS behaves very differently in some regards. I'll let you know if the data-only works, thanks for the quick support again.

@vipul-liv
Copy link

vipul-liv commented May 28, 2021

Hi guys, even I am facing the same issue in my IOS 14.3 device. I am using React-native-firebase/messaging library. onMessage works just fine but the real issue comes with setBackgroundMessageHandler. It doesn't get fired when the app is in the background. But when I reopen the app, the FCM notification fired while in the background comes up as foreground notification.
Please help here. My payload I am passing in REST API call -

{
"to":"xxxFCM-TOKENXXXXX",
"data" : {
"body" : "test message",
"title" : "test title",
"content_available" : true,
"priority" : "high"
}
}

Firebase libraries I am using -

"@react-native-firebase/app": "7.2.0",
"@react-native-firebase/auth": "8.0.4",
"@react-native-firebase/firestore": "7.1.5",
"@react-native-firebase/messaging": "7.1.4",

@rdsedmundo
Copy link

@VipulGarg26-liv The content_available and priority properties should be outside of the data key.

@vipul-liv
Copy link

Thanks @rdsedmundo , I made these changes. It worked just once. After that, I have been trying to hit the API again with the app being in the background state, but not getting the notification. API payload -
{
"to":"FCM Token",
"data" : {
"body" : "test message",
"title" : "Title Test"
},
"content_available" : true,
"priority" : "high"
}

@mikehardy
Copy link
Collaborator

You've got to launch the app on a real device from Xcode then watch the console very closely. You are probably being throttled somehow. If it worked once your code is likely good. Delivery of data-only messages on Apple is never guaranteed though, it is via the "content-available" flag for a reason - what that means precisely is "hey, you can update some content into your local content cache if you want, but it's okay if you don't because it's just a cache, if it's stale when the app opens the app will update it then"

Relying on it for delivery goes counter to it's documented not-guaranteed-delivery status as an API

@vipul-liv
Copy link

@mikehardy , I tried to look more closely into the code and tried to make some changes to the payload. But same behaviour for the notifications. All notifications fired for background state are being received on the app open via onMessage handler. Now I feel I might be wrong that it worked the first time. I think it was a foreground notification only which I got delayed.
Updated payload -
{
"to": "FCM Token",
"data": {
"body": "test message",
"title": "Title Testing"
},
"apns": {
"payload": {
"aps": {
"content_available": 1
}
}
},
"android": {
"priority": "high"
}
}

@vipul-liv
Copy link

Still unable to make this work. Any help on this would be helpful.

@isakki

This comment has been minimized.

@mikehardy

This comment has been minimized.

@timurridjanovic
Copy link

@mikehardy if the background handler is never called if you have a notification block, how do you update app state if the user receives the notification but instead of clicking on it, he just brings the app back in the foreground? My onMessage is only getting called if app is in foreground, not if app was in background and later on brought back in foreground.

@mikehardy
Copy link
Collaborator

I must admit, I'm not exactly sure, this is a very difficult part of mobile development, and in this exact area of firebase integrations there are parts of the solution that are controlled by firebase-ios-sdk with ability to use a native extension helper and parts in javascript where you have handlers you register. I think in this case, you want a native notification extension helper that somehow communicates with javascript (user prefs? I'm not sure what message passing channels might be best) and that way you may register notification receipt, and process the data block for use when the app comes back to foreground.

Another entirely different solution design might be to just query remote state on react-native AppState listener events so that you did not assume anything about notification contents (or delivery, or non-delivery) and just verified things and updated state every time when the app came to foreground

@timurridjanovic
Copy link

@mikehardy it seems like I'm able to receive messages in the background even with the notification block (notification + data), but for some reason the handler is called after like a 10 sec delay after receiving the "system notification".

@mikehardy
Copy link
Collaborator

@timurridjanovic indeed! You might like #5545 - but more importantly I think you will really like #5547 (which has patches available already and is on it's way to merge once it has final review)

@santitopo
Copy link

santitopo commented Aug 6, 2021

Hey guys, I went through the same problem as many people here, about setBackgroundMessageHandler not being called on new remote notification event when app in background/quit state. Reading this thread really helped me finding my way so here goes what finally worked for me.

I wanted to increase the badge number of my app every time I received a new notification, so I needed to execute some piece of code regardless of the app being in background or quit state. To do this, I added these to my index.js:

function HeadlessCheck({ isHeadless }) {
  if (isHeadless) {
    // App has been launched in the background by iOS, ignore
    return null;
  }
  return <App />;
}

 // handler when app in BACKGROUND
messaging().setBackgroundMessageHandler(async () => {.  
  increaseApplicationIconBadgeNumber();
});

 // handler when app in QUIT state
if (Platform.OS === 'ios') {
  messaging()
    .getInitialNotification()
    .then(() => increaseApplicationIconBadgeNumber());
}

AppRegistry.registerComponent('YourAppName', () => HeadlessCheck);

- Notice that I only use the getInitialNotification method for iOS, as Android handles the reception in quit state in a different way.

- I've noticed that in iOS with this setup, tapping on a notification when it's been received in quit state is being handled by onNotificationOpenedApp, which makes me think that even though the headless check, the app is considered to be in background state to the OS after being headlessly launched

As stated in the https://rnfirebase.io/messaging/usage documentation, the headless prop must be added to the startup process in the AppDelegate.m like this (so HeadlessCheck actually makes sense):

// add this import statement at the top of your `AppDelegate.m` file
#import "RNFBMessagingModule.h"

// in "(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions" method
// Use `addCustomPropsToUserProps` to pass in props for initialization of your app
// Or pass in `nil` if you have none as per below example
// For `withLaunchOptions` please pass in `launchOptions` object
NSDictionary *appProperties = [RNFBMessagingModule addCustomPropsToUserProps:nil withLaunchOptions:launchOptions];

// Find the `RCTRootView` instance and update the `initialProperties` with your `appProperties` instance
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                             moduleName:@"nameOfYourApp"
                                             initialProperties:appProperties];

Also, the notification structure that is working for me sent via Postman is the following :
URL: [POST] https://fcm.googleapis.com/fcm/send

Headers:

Authorization: key=YOUR_FCM_SERVER_KEY
Content-Type : application/json

Body:

 "to" : "DEVICE_FCM_TOKEN",
 "notification" : {
     "body" : "Body of Your Notification",
     "title": "Title of Your Notification"
 },
"content_available":true
}

Version used:
react-native-firebase/app & react-native-firebase/messaging version 12.4.0

Not exactly sure why setBackgroundMessageHandler is not handling the notifications on quit state (the documentation specifies that it should handle both background and quit reception), but still this is a working solution to cover all the cases... Hope to be of some help!

@luanccp
Copy link

luanccp commented Sep 2, 2021

Still no working for me, nothing happens when my app is in the QUIT state 😞

@hamza-novalabs
Copy link

@VipulGarg26-liv and @samleurs247, The flag is supposed to be content-available and not content_available or contentAvailable.
Setting the correct flag solved it for me.

@peterhuijsen
Copy link

Also not working for me, tried everything from setting content-available to true (or 1), adding headers, using separate messages (one for data, one for the notification). setBackgroundMessageHandler IS called before the initialization of the actual react app.

@work4m
Copy link

work4m commented Jan 21, 2022

Hi, I resolve it after atleast two weeks and my configurations are as below

  1. My Node API update as below
    nodeAPI

  2. My root index.js as below
    appNotification

  3. I added following lines in AppDelegate.m is as below

Screenshot 2022-01-21 at 1 06 28 PM

Screenshot 2022-01-21 at 1 02 21 PM

  1. Most important thing which I had forgot to put in xcode 🥲
    You must add following Capabilities

Screenshot 2022-01-21 at 12 57 47 PM

@toioski
Copy link

toioski commented Jan 21, 2022

I lost my mind over this issue for days like many of you and I think I've realized the sad truth: it's not possible to increment the badge counter on iOS using setBackgroundMessageHandler. That method is not meant for that.

The documentation of Notifee is providing the following example that, as far as I understood, it will never ever work:

// Your app's background handler for incoming remote messages
firebase.messaging().setBackgroundMessageHandler(async (
  remoteMessage: FirebaseMessagingTypes.RemoteMessage
) => {
   await notifee.displayNotification(...)
   // Increment the count by 1
   await notifee.incrementBadgeCount();
})

Apple doesn't allow that code to run when the app is either closed or in the background. Sadly, the only way to implement the badge count on iOS is to actually send with the FCM itself a key badge with the correct badge count. It means that every time we send a push to a device we also need to keep track in a persistent layer like a DB the number of push notifications sent to a user. Once the user opens the app, we will reset the count to zero both on the device itself via a native call and on the persistent layer with an HTTP call.

SosetBackgroundMessageHandler is working absolutely fine and I want to thank this comment #3530 (comment) that guided me in the right direction.

P.S. I still wish I am wrong about this whole topic 😆

@mikehardy
Copy link
Collaborator

Re: "cheated by notifee documentation" - it's all open source, it's your documentation now ;-), I mean we try our hardest but if something is wrong please please post a PR to the docs, happy to merge any reasonable PRs

Interesting that isn't working through, as I'm guessing @helenaford would not have put that in there (and it must have been her, it was definitely not me and I think we're the only two usually in there...) if she had not tested it and it worked 🤔

That said, you may be able to do it with an extension handler perhaps? https://notifee.app/react-native/docs/ios/remote-notification-support#add-the-notification-service-extension

@toioski
Copy link

toioski commented Jan 21, 2022

@mikehardy sorry for the bad wording, it wasn't absolutely my intention to offend anyone. The opposite: I believe Notifee it's a great library, with great people behind that are way more expert than me. Indeed I thought: "I must be doing something wrong if it's not working and the docs suggest that that's the way to do it!", but after many hours I realized that eventually, I was right.

That said, you may be able to do it with an extension handler perhaps? https://notifee.app/react-native/docs/ios/remote-> notification-support#add-the-notification-service-extension

I have checked the doc, but I don't think is feasible even with the extension. There's no way to say through the FCM message itself "increment the badge count by 1". We have to explicitly specify the actual number we wanna display on the badge.

@mikehardy
Copy link
Collaborator

:-) - no worries, I am not easily offended, and I added the smiley even after that statement as it was intended more light-hearted. That said, we do really love docs PRs - I hate to hear developers losing time to problems where the time could be saved with a couple well-written sentences...

@santitopo
Copy link

santitopo commented Jan 21, 2022

I lost my mind over this issue for days like many of you and I think I've realized the sad truth: it's not possible to increment the badge counter on iOS using setBackgroundMessageHandler. That method is not meant for that.

The documentation of Notifee is providing the following example that, as far as I understood, it will never ever work:

// Your app's background handler for incoming remote messages
firebase.messaging().setBackgroundMessageHandler(async (
  remoteMessage: FirebaseMessagingTypes.RemoteMessage
) => {
   await notifee.displayNotification(...)
   // Increment the count by 1
   await notifee.incrementBadgeCount();
})

Apple doesn't allow that code to run when the app is either closed or in the background. Sadly, the only way to implement the badge count on iOS is to actually send with the FCM itself a key badge with the correct badge count. It means that every time we send a push to a device we also need to keep track in a persistent layer like a DB the number of push notifications sent to a user. Once the user opens the app, we will reset the count to zero both on the device itself via a native call and on the persistent layer with an HTTP call.

SosetBackgroundMessageHandler is working absolutely fine and I want to thank this comment #3530 (comment) that guided me in the right direction.

P.S. I still wish I am wrong about this whole topic 😆

@toioski Your scenario seems pretty similar to mine back then (#4705 (comment)). I must say that even though I couldn't manage to make the badge number update in quit state with the setBackgroundMessageHandler, I DID make it work with getInitialNotification().

My understanding is that the incoming notification wakes the app in background in a headless mode, so by adding the HeadlessCheck logic on startup and the getInitialNotification handler you should be good to go. I recall the badge number updating after a few seconds (the time it takes for iOS to wake up the app in background).

// handler when app in QUIT state
if (Platform.OS === 'ios') {
  messaging()
    .getInitialNotification()
    .then(() => increaseApplicationIconBadgeNumber());
}

The badge number bump was being made using react-native-push-notification but I guess that part would work just the same way with Notifee.

To be completely honest though I ended up ripping off that whole logic and preferred to do it the way you suggest, handled by the BE. In my case, it was intended to show the # of unread messages in a chat, so it was quite easy to keep track of that without the need to count the push notifications sent to the client.

@toioski
Copy link

toioski commented Jan 21, 2022

@santitopo thanks a lot for your input, very much appreciated! I have already tried what you're suggesting but unfortunately isn't working for me. This is the exact code I wrote on the index.js file of my app:

// File: index.js

messaging()
  .getInitialNotification()
  .then(remoteMessage => {
    notifee.incrementBadgeCount()
})


const HeadlessCheck = ({ isHeadless }) => {
  // App has been launched in the background by iOS, ignore
  if (isHeadless) return null

  return <App />
}

AppRegistry.registerComponent(appName, () => HeadlessCheck)

I don't think the fact the badge isn't incrementing relates to Notifee because in all the other scenarios the API .incrementBadgeCount() is properly working. On top of this, in my case, I can't manage to get it working on both app-in-background and app-quit scenarios. Instead, in this comment #4705 (comment), you were using getInitialNotification only for the app-quit case.

@santitopo
Copy link

I don't think the fact the badge isn't incrementing relates to Notifee because in all the other scenarios the API .incrementBadgeCount() is properly working. On top of this, in my case, I can't manage to get it working on both app-in-background and app-quit scenarios. Instead, in this comment #4705 (comment), you were using getInitialNotification only for the app-quit case.

@toioski Ok so I'm assuming you are 100% sure notifee.incrementBadgeCount() is not the problem. Have you tried logging smth on that getInitialNotification callback to see if by any chance it is getting triggered without you noticing it?

The other thing that you might be missing (though I also mentioned that in my earlier message) is the setup in the AppDelegate.m to add the headless prop. Or... maybe it could be related to the specific body of the notification you are sending (Is it data only and is content-available set to true?).

Also do check that you have enabled Background fetch in the xcode project background modes.

Good luck!

@toioski
Copy link

toioski commented Jan 21, 2022

@santitopo yes, I have tried:

  1. to log something on getInitialNotification. I don't see anything either on Metro or on Xcode
  2. I am injecting the isHeadless prop
  3. I have enabled the Background fetch capability

It sounds so weird to me that you had it working at some point 😞

@rafawhitee
Copy link

I have a same issue on react-native-firebase 14.2.3, on iOS works only foregorund, background or quit doesn't.

"@react-native-firebase/app": "14.2.3",
"@react-native-firebase/messaging": "14.2.3",

on my setBackgroundMessageHandler, i'm using AsyncStorage to storage the last message background/quit, so when i click on notification and open app, i checked the last message on storage to show (if never opened):

messaging().setBackgroundMessageHandler(async remoteMessage => {
if (remoteMessage) {
var riobutcherNotification = createRiobutcherNotification(remoteMessage, true);
await createOrUpdateNotification(riobutcherNotification)
}
});

@NguyenVanVietPoLy
Copy link

NguyenVanVietPoLy commented Sep 19, 2022

i missing this code , paste in appdelege.m that work fine.
// add this import statement at the top of your AppDelegate.m file
#import "RNFBMessagingModule.h"

// in "(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions" method
// Use addCustomPropsToUserProps to pass in props for initialization of your app
// Or pass in nil if you have none as per below example
// For withLaunchOptions please pass in launchOptions object
NSDictionary *appProperties = [RNFBMessagingModule addCustomPropsToUserProps:nil withLaunchOptions:launchOptions];

// Find the RCTRootView instance and update the initialProperties with your appProperties instance
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"nameOfYourApp"
initialProperties:appProperties];

@julianramireze
Copy link

Thanks @rdsedmundo , I made these changes. It worked just once. After that, I have been trying to hit the API again with the app being in the background state, but not getting the notification. API payload - { "to":"FCM Token", "data" : { "body" : "test message", "title" : "Title Test" }, "content_available" : true, "priority" : "high" }

this works, content_available for ios notifications and priority high for android.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help: needs-triage Issue needs additional investigation/triaging. type: bug New bug report
Projects
None yet
Development

No branches or pull requests