-
Notifications
You must be signed in to change notification settings - Fork 2.2k
[🐛] setBackgroundMessageHandler not working on ios #4705
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
Comments
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. |
"@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 |
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 |
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)) |
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);
}); |
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 |
I'm facing the same issue here. My index.js-file looks like this:
Some other important things:
Edit:
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: |
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? |
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" |
I can't get 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 I have tried both with the headless prop and without it, same results. |
Please use precise terms, it's important, I will be pedantic about it. 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 ( This is subtle. But it's also all documented. |
You're correct about all assumptions, I sent an FCM with a payload containing a notification and data in it.
Where in the documentation is that stated? This is not what I understand reading this table. It clearly says that Also here it says:
|
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. |
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 |
@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 |
No, I still couldn't make it to work via the
Because I'm sending a full notification and not data-only if the user clicks the notification I can get the data using Do you know of any tricks to avoid the Apple throlling while in development? For example, reinstalling the app completely? |
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. |
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'm in the same situation where I have both 'notification' and 'data' in the payload |
I see, but this works on Android for what it's worth: data+notification calls |
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. { Firebase libraries I am using - "@react-native-firebase/app": "7.2.0", |
@VipulGarg26-liv The |
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 - |
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 |
@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. |
Still unable to make this work. Any help on this would be helpful. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@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. |
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 |
@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". |
@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) |
Hey guys, I went through the same problem as many people here, about 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 - 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 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):
Also, the notification structure that is working for me sent via Postman is the following : Headers:
Body:
Version used: Not exactly sure why |
Still no working for me, nothing happens when my app is in the QUIT state 😞 |
@VipulGarg26-liv and @samleurs247, The flag is supposed to be |
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). |
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 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 So P.S. I still wish I am wrong about this whole topic 😆 |
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 |
@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.
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. |
:-) - 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... |
@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 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. |
@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 // 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 |
@toioski Ok so I'm assuming you are 100% sure 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 Also do check that you have enabled Good luck! |
@santitopo yes, I have tried:
It sounds so weird to me that you had it working at some point 😞 |
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", 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 => { |
i missing this code , paste in appdelege.m that work fine. // in "(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions" method // Find the |
this works, content_available for ios notifications and priority high for android. |
setBackgroundMessageHandler is not working in ios on android working fine.
Payload Admin :
index.js
ios podfile
Override Firebase SDK Version
$FirebaseSDKVersion = '7.0.0'
package.json
The text was updated successfully, but these errors were encountered: