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

iOS background handler not always triggered #4104

Closed
1 of 5 tasks
compojoom opened this issue Aug 19, 2020 · 34 comments · Fixed by #4180
Closed
1 of 5 tasks

iOS background handler not always triggered #4104

compojoom opened this issue Aug 19, 2020 · 34 comments · Fixed by #4180
Assignees
Labels
platform: ios plugin: messaging FCM only - ( messaging() ) - do not use for Notifications type: bug New bug report

Comments

@compojoom
Copy link
Contributor

I've spend more time debugging this than I'm comfortable admitting, but well that's life.

If you were to search this repo for "ios background" -> you'll find around 30 open issues. Which makes 30% of all open issues. To those of you who think that react-native-firebase doesn't work with ios background notifications - you are wrong. It works! I've been in that boat and I can tell you - it works. Make sure that you compose the right message, with the correct headers. If your app is still not woken up, then use the console.app on your Mac to find out if iOS is blocking the push notifications for some reason.

Putting those things aside. I could see that our app was being woken up, but the JS backgroundHandler was not being triggered. Initially I thought that we have a bug in our JS code as the moment I commented some lines out - I could see the handler working. After some time - I noticed that it's not always the same commented out lines that make it work. It was all kind of random. I'll comment a line out - and it would work. Then I'll re-enable this line and it will continue to work... So I thought that we must be having some race condition in our code that provokes this. But after few days I realized that the part that causes this is not in our JS code, but rather on the native side. More precisely here:

      // TODO investigate later - RN bridge gets invalidated at start when in background and a new bridge created - losing all events
      // TODO   so we just delay sending the event for a few seconds as a workaround
      // TODO   most likely Remote Debugging causing bridge to be invalidated
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_message_received_background" body:[RNFBMessagingSerializer remoteMessageUserInfoToDict:userInfo]];
      });

https://github.com/invertase/react-native-firebase/blob/master/packages/messaging/ios/RNFBMessaging/RNFBMessaging%2BAppDelegate.m#L122

In our app the background task actually needs to load the redux store and the redux-saga code. We are talking about a lot of imports. So it turned out that despite setting the listener as one of the first things in index.js we apparently need more than 2s. I increased this to 8s and I can confirm that we are now receiving the message all the time.

So with this knowledge I think that some of the users who have opened a "ios background data message" issue actually suffer from the above problem. The OS actually delivers the message to the app, but the native code is executed before the bundle is ready and they are left with no message.

Environment

Click To Expand

react-native info output:

System:
OS: macOS 10.15.6
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Memory: 247.13 MB / 32.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 14.4.0 - /usr/local/bin/node
Yarn: 1.17.3 - /usr/local/bin/yarn
npm: 6.14.4 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.9.1 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: iOS 13.6, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
Android SDK:
API Levels: 28, 29
Build Tools: 28.0.3, 29.0.0, 29.0.2, 29.0.3
System Images: android-24 | Google Play Intel x86 Atom, android-28 | Intel x86 Atom_64, android-28 | Google Play Intel x86 Atom, android-29 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom
Android NDK: 19.0.5232133
IDEs:
Android Studio: 4.0 AI-193.6911.18.40.6514223
Xcode: 11.6/11E708 - /usr/bin/xcodebuild
Languages:
Java: 1.8.0_222 - /usr/bin/javac
Python: 2.7.16 - /usr/bin/python
npmPackages:
@react-native-community/cli: Not Found
react: 16.11.0 => 16.11.0
react-native: 0.62.2 => 0.62.2

  • 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:
    "8.3.0",

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

    • "@react-native-firebase/messaging": "7.6.1",
  • Are you using TypeScript?

    • N

@mikehardy
Copy link
Collaborator

This would go a long way to explaining some of the non-deterministic behavior some people have seen, especially I remember a couple redux-saga folks mentioning this. Great digging

We'll see if we can make this less "hard-coded delay that should work" and more either configurable delay (not great but would be better) or "actually event based" (best option, most likely)

Community contributions are driving the repo though, so if you (or anyone else reading this) has ideas, a PR directly submitted will be the fastest way to fix, as with any issue

@compojoom you specifically could reach right in there and make it work for yourself now (so as not to be blocked) and persist that with patch-package while we work through the details

@andersonaddo andersonaddo added platform: ios plugin: messaging FCM only - ( messaging() ) - do not use for Notifications labels Aug 19, 2020
@andersonaddo
Copy link
Contributor

Wow, this is a great find! Will help this repo a ton if it gets merged 🤞🏽

@Salakar
Copy link
Member

Salakar commented Aug 19, 2020

Hey Daniel!

Was chatting about this internally and the way our event emitter works on iOS & Android is that the events are corked/pooled on native until JS tells native it's ready, https://github.com/invertase/react-native-firebase/blob/master/packages/app/ios/RNFBApp/RNFBRCTEventEmitter.m#L61

So only once JS has loaded does these events get uncorked and they flow through to JS, this happens here: https://github.com/invertase/react-native-firebase/blob/master/packages/app/lib/internal/RNFBNativeEventEmitter.js#L30

Perhaps whats happening here is that in that JS code we need to add the listener first before calling that ready method, right now it's telling native it's ready then adding the subscription after - and the event could be getting lost as the listener isn't registered yet

Could you try swapping them around in the JS code?

@compojoom
Copy link
Contributor Author

Modify it like this?

  addListener(eventType, listener, context) {
    RNFBAppModule.eventsAddListener(eventType);
    const listeners = super.addListener(`rnfb_${eventType}`, listener, context);
    if (!this.ready) {
      RNFBAppModule.eventsNotifyReady(true);
      this.ready = true;
    }

    return listeners
  }

Not sure if that is what you want, but I tried it and it doesn't seem to work. I'm not receiving the message with that change.

@compojoom
Copy link
Contributor Author

compojoom commented Aug 26, 2020

I'm attaching a patch that can be used with patch-package (for those that don't want to manually modify obj-c files).
@react-native-firebase+messaging+7.6.1.patch.zip

in this discussion another user confirmed that the modification to AppDelegate helped him.
#4141

@Salakar Salakar added the type: bug New bug report label Aug 26, 2020
@Salakar
Copy link
Member

Salakar commented Aug 26, 2020

Perhaps we can do a temporary fix of this to increase the timing to 8s whilst a more permanent solution is being worked on that isn't time based. Could you send a PR for that Daniel and I'll get it merged and published today

compojoom added a commit to compojoom/react-native-firebase that referenced this issue Aug 26, 2020
This should be viewed as a temporary fix.
A lot of people are reporting that the background data messages on iOS are not being delivered. The app wakes up, but the background listener doesn’t receive the message. Some apps that have a lot of JS apparently need more than the 2s timeout to be ready. So what happens is - app is started, 2s elapse, RNFBMessaging sends the message to the js handler, but the JS handler is not ready yet and misses the message. We mitigate this by delaying the delivery of the message to the JS side.

This solution however is not optimal becasue we are sending a completionHandler after about 25s which means that our JS code would have only 16 to do something with the data message.

A correct fix would be to figure out how to dispatch the message once the JS side is actually ready.

invertase#4104
@Salakar
Copy link
Member

Salakar commented Aug 26, 2020

@react-native-firebase/[email protected] has been released with the temporary fix

@davx1992
Copy link
Contributor

Had same issue, this helped me also. But for me 4/5 seconds is enough and messages were handled.

@mikehardy
Copy link
Collaborator

@davx1992 cross-linking you to this issue, @russellwheatley I think you were thinking about looking at this? I might be wrong - sorry if so - either way, some new findings in user testing documented here #3805 (comment)

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_message_received_background" body:[RNFBMessagingSerializer remoteMessageUserInfoToDict:userInfo]];
});

when I take it out, and leave without dispatch_after it works. Also what I found out, that dispatch_after is not triggered on first message, after it is backgrounded.
I am not skilled with Obj.c. maybe you have any idea, what could cause such behaviour?

I would like to keep this centralized - it is a tough issue and will require lots of detail, having it one spot will help

@davx1992
Copy link
Contributor

davx1992 commented Aug 29, 2020

Hello All, I think I found a solution for my problem. After a few hours of googling and learning Obj.c. found possible solution.
So, as I understood, in IOs, when app is suspended, the background code is not executed, except when it is Background task.
As I found out then messages, are received, but dispatches are not executed.
So I added background task to this method and clearing it after dispatch executed. After testing, I see that each message is handled, and no issue observed. Would like to ask other people to test, it and if you are pro in Objc I would be thankful if someone could confirm my approach, Thanks in advance. Below is my code, which is working now.

(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
    
    NSLog(@"Recevied message");

  #if __has_include(<FirebaseAuth/FirebaseAuth.h>)
  if ([[FIRAuth auth] canHandleNotification:userInfo]) {
    completionHandler(UIBackgroundFetchResultNoData);
    return;
  }
  #endif
  
  [[NSNotificationCenter defaultCenter] postNotificationName:@"RNFBMessagingDidReceiveRemoteNotification" object:userInfo];

  if (userInfo[@"gcm.message_id"]) {
    if ([UIApplication sharedApplication].applicationState ==      UIApplicationStateBackground) {
        
        UIBackgroundTaskIdentifier __block backgroundTaskId = [application beginBackgroundTaskWithExpirationHandler:^{
             if (backgroundTaskId != UIBackgroundTaskInvalid) {
                 [application endBackgroundTask:backgroundTaskId];
                 backgroundTaskId = UIBackgroundTaskInvalid;
             }
        }];

        // TODO add support in a later version for calling completion handler directly from JS when user JS code complete
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (25 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

          NSLog(@"Recevied message complete handler");
          completionHandler(UIBackgroundFetchResultNewData);

        //Stoping background task
        if (backgroundTaskId != UIBackgroundTaskInvalid) {
            [application endBackgroundTask:backgroundTaskId];
            backgroundTaskId = UIBackgroundTaskInvalid;
        }
        });

        // TODO investigate later - RN bridge gets invalidated at start when in background and a new bridge created - losing all events
        // TODO   so we just delay sending the event for a few seconds as a workaround
        // TODO   most likely Remote Debugging causing bridge to be invalidated
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
              NSLog(@"Recevied message after dispatch ");

              [[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_message_received_background" body:[RNFBMessagingSerializer remoteMessageUserInfoToDict:userInfo]];
        });
    } else {
      [[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_message_received" body:[RNFBMessagingSerializer remoteMessageUserInfoToDict:userInfo]];
      completionHandler(UIBackgroundFetchResultNoData);
    }
  }
}

Only question left for me, is where is the best place to end bg task, when messaging_message_received_background or on when completion handler called.

@mikehardy
Copy link
Collaborator

@davx1992 why is that necessary in the context of the initialization/handling infrastructure here: https://github.com/invertase/react-native-firebase/tree/master/packages/messaging/ios/RNFBMessaging and with reported user success in almost all situations?

More specifically: what exact cases are not handled by existing code (with links to line numbers and what's missing)

@davx1992
Copy link
Contributor

@mikehardy Will try to explain. So the initial problem which was reported in this issue was partially fixed by this WA - extending timeout. This WA fixed issue, that handler is not triggered when app was in quit state.
unfortunately, I tested this WA when I had running background task - expo-location background location updates, so I have not noticed any issue with this.
When I disabled background location updates, I faced a new issue - when the app is in the background state, when a message is sent, and the receiver method is triggered, dispatch_after methods are not triggered. Those are the below lines.

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (25 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
          completionHandler(UIBackgroundFetchResultNewData);
 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
              [[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_message_received_background" body:[RNFBMessagingSerializer remoteMessageUserInfoToDict:userInfo]];
        });

As I found the information in google, then the queue is not executed when app is in the background state.
_When an app is suspended, the entire process is frozen. You can count on the process resuming as if nothing happened at all once it is resumed. _

It means that when the message received, all sync code is being executed, but this async code is not executed. And this explains the behavior that the message which was received, is handled only when the app is resumed, or the next message received, then the queue executes the previous code.

To fix this, I implemented a background task, which is registering a background task, and when complete handler executed, I clear background task. This is fixing an issue, that queue is not frozen, and is dispatch_after being executed.
So what I did, when the message is received, and it app is in the background state, then I register background task with below code:

UIBackgroundTaskIdentifier __block backgroundTaskId = [application beginBackgroundTaskWithExpirationHandler:^{
             if (backgroundTaskId != UIBackgroundTaskInvalid) {
                 [application endBackgroundTask:backgroundTaskId];
                 backgroundTaskId = UIBackgroundTaskInvalid;
             }
        }];

Then when we are calling complete handler, I am clearing background task:

        // TODO add support in a later version for calling completion handler directly from JS when user JS code complete
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (25 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

          NSLog(@"Recevied message complete handler");
          completionHandler(UIBackgroundFetchResultNewData);

        //Stoping background task
        if (backgroundTaskId != UIBackgroundTaskInvalid) {
            [application endBackgroundTask:backgroundTaskId];
            backgroundTaskId = UIBackgroundTaskInvalid;
        }
        });

@mikehardy
Copy link
Collaborator

@davx1992 fascinating! Great explanation, thank you. If you could put this in a PR we could review and either ingest it (to solve yet another facet of this endless problem!) or re-shape it to solve the root cause you've found somehow / some way.

@mikehardy mikehardy added Workflow: Needs Review Pending feedback or review from a maintainer. Workflow: Waiting for User Response Blocked waiting for user response. labels Aug 30, 2020
@davx1992
Copy link
Contributor

@mikehardy will try to do this, found info on this.

@mikehardy
Copy link
Collaborator

@davx1992 your PR looked great, passed review and I just merged, I'll get a release out shortly after our CI tests run through it to make sure it landed on the main branch successfully. Fantastic work - we are slowly - one by one - fixing all the corner cases that cause FCM receipt to fail.

@mikehardy mikehardy removed Workflow: Needs Review Pending feedback or review from a maintainer. Workflow: Waiting for User Response Blocked waiting for user response. labels Aug 31, 2020
@davx1992
Copy link
Contributor

@mikehardy Great to hear that! Thanks!

@mikehardy
Copy link
Collaborator

Here's what I posted on the other ones as I closed them, same applies here - we think everything can work now, and if there are still failures we need extra care to see an App.js that cleanly reproduces it:


As part of the work on #4104 several PRs have been merged, including one just merged and released now as @react-native-firebase/7.8.4

We believe FCM messages will be handled now:

  • if you set content-available and priority headers correctly in your JSON payload
  • if you are on a real device
  • if the app is not running and your javascript bundle boots within 8 seconds (careful, redux-saga users! from a patch a few days ago)
  • if the app is in the background (with the most recent patch)

We are no longer aware of cases that don't have known solutions.

If you can reproduce a case after updating to the latest code and running npx react-native-clean-project to make sure you have a clean build, please open a new issue post an App.js that demonstrates the problem.

@acarpe
Copy link

acarpe commented Sep 4, 2020

@davx1992 @mikehardy in order to make this solution works, one should enable the "Background processing" capability in the app?

@davx1992
Copy link
Contributor

davx1992 commented Sep 4, 2020

It doesn't work for you? In my project, I have Background Processing.

@mikehardy
Copy link
Collaborator

@acarpe there is never a time you will succeed without doing all the listed-as-required steps: https://rnfirebase.io/messaging/usage/ios-setup#enable-background-modes

@acarpe
Copy link

acarpe commented Sep 5, 2020

First things first... I'm not an iOS dev expert :)
@mikehardy I followed the documentation but the "Background processing" in the guide is not mentioned to be checked (and in the gif too it remains unchecked) but because the @davx1992 's solution is based on background task I though it is now required that capability too.

@davx1992 I'm trying to clean up my app code to isolate if that capability is required or not but it could take me some days :(, right now I have enabled it.

@mikehardy
Copy link
Collaborator

@acarpe

It took me a moment to figure it out because I am also not a iOS dev expert - I was confusing which ability was which. There is a new "Background Tasks" API for iOS13+ that is used (among other places) by react-native-background-fetch optionally, but I think this is different.

This explains all the background modes:

https://developer.apple.com/documentation/backgroundtasks/choosing_background_strategies_for_your_app

I believe the call in the PR we just merged - https://developer.apple.com/documentation/uikit/uiapplication/1623031-beginbackgroundtaskwithexpiratio - available since iOS 4, requires no special permission to use, as opposed to the new full-featured Background Tasks API which does require permission

@davx1992 did I get that right to your knowledge ?

@nishanttatva
Copy link

@davx1992
Can you please clarify whether it's required to enable "Background Processing" to get the messaging().setBackgroundMessageHandler to be called after this change?

I cannot get this method to be called when sending data-only push to the iOS app, when its totally killed (swiped-up and killed).

@davx1992
Copy link
Contributor

@nishanttatva as I see from above information mentioned by Mike then no. (I am also not an IOS expert).
Best for this is just try add it and check if it works. If app is not killed is it working?
Also keep in mind that Data messages are not guaranteed to be delivered, as IOS can decide not to wake up your app. Had same issue, and nothing could be done there..

@mikehardy
Copy link
Collaborator

If you swipe the app away iOS believes you. You just said "go away". iOS will not wake the app again for data-only things. If you send a visible notification the underlying SDKs will post the notification to the notification center but you will not see your app wake up and you get no opportunity to run code again until the user interacts with the notification (which the iOS understands as "okay, the user wants to use the app again").

@nishanttatva
Copy link

nishanttatva commented Sep 17, 2020

@davx1992

Best for this is just try add it and check if it works. If app is not killed is it working?

Tried it, doesn't change anything. And yes all other cases, as in app in foreground (onMessage is called), or background (setBackgroundMessageHandler is called) work as intended.

@mikehardy
Okay, then there's no way to call the setBackgroundMessageHandler when app is in Quit state in iOS? If that's the case, maybe this documentation needs to change? Or is it that my understanding that Quit = Killed(swiped away) is incorrect?

According to the docs,

Background Application State

On iOS however, when a message is received the device silently starts your application in a background state. At this point, your background handler (via setBackgroundMessageHandler) is triggered, but your root React component also gets mounted. This can be problematic for some users since any side-effects will be called inside of your app (e.g. useEffects, analytics events/triggers etc). To get around this problem, you can configure your AppDelegate.m file (see instructions below) to inject a isHeadless prop into your root component

I've been debugging this since 2 days, at my wits end now.

@mikehardy
Copy link
Collaborator

Quit != Killed/Swiped

Quit is just that it went to the background and then the OS harvested the resources. iOS is aggressive about this, but will wake your app again.

If the user kills or swipes the app though iOS takes the user at their "word" and your app is dead until interacted with again

@nishanttatva
Copy link

@mikehardy
Ohh I see! That's a bummer!

@mikehardy
Copy link
Collaborator

If I understand correctly Android does something similar but only with the "force close" button, or on new app install. Until the app runs again (which is a user interaction), you don't receive any broadcast intents. From a programmer perspective it could be perceived as a bummer but as a user it's fantastic, they should have the control.

Options available as programmer are cloud message with notification payload (hope the user taps it!), be a VOIP app (I kid, but it is a path), hook to Motion or Location events (but you better have a reason! or you will be denied) and that's about it. Gotta craft an app the user is motivated to use

@nishanttatva
Copy link

@mikehardy
Another interesting thing is that user on iOS 13.x is experiencing this issue.

i.e App is background, data-only push is sent, and app is not opened for some time. When app is opened, its crashed. Idk, if this is related to it.

@mikehardy
Copy link
Collaborator

Post a stack trace. If it is the same, it is possibly related

@georgetk
Copy link

georgetk commented Oct 1, 2020

Just a heads-up on how I moved from setBackgroundMessageHandler #4310 (comment)

@jeet-parshwa
Copy link

jeet-parshwa commented Dec 19, 2020

Hello All, I think I found a solution for my problem. After a few hours of googling and learning Obj.c. found possible solution.
So, as I understood, in IOs, when app is suspended, the background code is not executed, except when it is Background task.
As I found out then messages, are received, but dispatches are not executed.
So I added background task to this method and clearing it after dispatch executed. After testing, I see that each message is handled, and no issue observed. Would like to ask other people to test, it and if you are pro in Objc I would be thankful if someone could confirm my approach, Thanks in advance. Below is my code, which is working now.

(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
    
    NSLog(@"Recevied message");

  #if __has_include(<FirebaseAuth/FirebaseAuth.h>)
  if ([[FIRAuth auth] canHandleNotification:userInfo]) {
    completionHandler(UIBackgroundFetchResultNoData);
    return;
  }
  #endif
  
  [[NSNotificationCenter defaultCenter] postNotificationName:@"RNFBMessagingDidReceiveRemoteNotification" object:userInfo];

  if (userInfo[@"gcm.message_id"]) {
    if ([UIApplication sharedApplication].applicationState ==      UIApplicationStateBackground) {
        
        UIBackgroundTaskIdentifier __block backgroundTaskId = [application beginBackgroundTaskWithExpirationHandler:^{
             if (backgroundTaskId != UIBackgroundTaskInvalid) {
                 [application endBackgroundTask:backgroundTaskId];
                 backgroundTaskId = UIBackgroundTaskInvalid;
             }
        }];

        // TODO add support in a later version for calling completion handler directly from JS when user JS code complete
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (25 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

          NSLog(@"Recevied message complete handler");
          completionHandler(UIBackgroundFetchResultNewData);

        //Stoping background task
        if (backgroundTaskId != UIBackgroundTaskInvalid) {
            [application endBackgroundTask:backgroundTaskId];
            backgroundTaskId = UIBackgroundTaskInvalid;
        }
        });

        // TODO investigate later - RN bridge gets invalidated at start when in background and a new bridge created - losing all events
        // TODO   so we just delay sending the event for a few seconds as a workaround
        // TODO   most likely Remote Debugging causing bridge to be invalidated
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
              NSLog(@"Recevied message after dispatch ");

              [[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_message_received_background" body:[RNFBMessagingSerializer remoteMessageUserInfoToDict:userInfo]];
        });
    } else {
      [[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_message_received" body:[RNFBMessagingSerializer remoteMessageUserInfoToDict:userInfo]];
      completionHandler(UIBackgroundFetchResultNoData);
    }
  }
}

Only question left for me, is where is the best place to end bg task, when messaging_message_received_background or on when completion handler called.

Can you tell me if this is working or not and if yes so in which file should i put it.

@9r4ik
Copy link

9r4ik commented Jan 11, 2022

same issues with some iphone`s(iphone 12 work). Its iisues from firebase. messaging.setBackgroundMessageHandler not triggered when data-only

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform: ios plugin: messaging FCM only - ( messaging() ) - do not use for Notifications type: bug New bug report
Projects
None yet
Development

Successfully merging a pull request may close this issue.