React-native-fcm: How does it work in the background?

Created on 9 Feb 2017  Â·  29Comments  Â·  Source: evollu/react-native-fcm

Xcode Background mode set remote notifications

but Background notification not working

please help

  sendNotificationWithData(token, data) {

    let body = {
      "to": token,
      "notification":{
        "title": "",
        "body": data,
        "sound": "default",
        "click_action": "fcm.ACTION.HELLO"
      },
      "data":{
        "title": "",
        "body": data,
        "click_action": "fcm.ACTION.HELLO",
        "remote": true
      },
      "priority": "high"
    }

    this._send(JSON.stringify(body), "notification-data");
  }

```
this.notificationListner = FCM.on(FCMEvent.Notification, notif => {
console.log("Notification", notif);
if(notif.local_notification){
return;
}
if(notif.opened_from_tray){
return;
}

  if(Platform.OS ==='ios'){
    //optional
    //iOS requires developers to call completionHandler to end notification process. If you do not call it your background remote notifications could be throttled, to read more about it see the above documentation link.
    //This library handles it for you automatically with default behavior (for remote notification, finish with NoData; for WillPresent, finish depend on "show_in_foreground"). However if you want to return different result, follow the following code to override
    //notif._notificationType is available for iOS platfrom
    switch(notif._notificationType){
      case NotificationType.Remote:
      notif.finish(RemoteNotificationResult.NewData) //other types available: RemoteNotificationResult.NewData, RemoteNotificationResult.ResultFailed
      break;
      case NotificationType.NotificationResponse:
      notif.finish();
      break;
      case NotificationType.WillPresent:
      notif.finish(WillPresentNotificationResult.All) //other types available: WillPresentNotificationResult.None
      break;
    }
  }
  this.showLocalNotification(notif);
});

```

Most helpful comment

I was having the same issue and finally got it working. It turns out I didn't import the p12 certificate into Firebase and make sure it matches the provisioning profile in the app. None of the instructions really mention it very clearly, this is the closest I found. https://firebase.google.com/docs/cloud-messaging/ios/certs

All 29 comments

same problem, i have checkmarks with Push Notifications and Background Modes(Background Fetch, Remote Notifications) in Capabalities

@andryuwka I am working. check these.
Android work well?? I background don't work popup. just notification alram

  • Create the Provisioning Profile
    -.p12 key

https://firebase.google.com/docs/cloud-messaging/ios/certs

yes, android works fine. iOS version does not receive push notifications in background, and in foreground receives some broken objects and logs it to console(presents yellow box with some error)

Same for me. iOS version does not receive push notifications in the background!

Here the same, iOS works only when the app is in foreground. Android is not affected by this issue.

Here is my configuration:

"react": "15.4.2",
"react-native": "0.41.2",
"react-native-fcm": "6.0.2"

try add "content_available" flag

{
  to: 'xxx',
  content_available: true,
  collapse_key: '',
  data: { show_in_foreground: true, remote: true },
  notification:
   {
     custom_notification: { icon: 'icon_notification', large_icon: 'ic_launcher' },
     title: 'Title of your push notification',
     body: 'Body of your push notification'
   },
  priority: 'high' 
}

And the notification only shows up when I open the application. On android it works perfectly. Does this package/firebase works on iOS, in the background?

have you set AppDelegate.m correctly?
Have you requested push notification permission?

component will mount

FCM.requestPermissions(); // and I pressed yes when it asked for my permission

AppDelegate.m

  [FIRApp configure];
  [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
  return YES;
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
 {
    [RNFIRMessaging willPresentNotification:notification withCompletionHandler:completionHandler];
 }

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
 {
    [RNFIRMessaging didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
 }

 //You can skip this method if you don't want to use local notification
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
    [RNFIRMessaging didReceiveLocalNotification:notification];
  }

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

I don't know what could have I done wrong (Background Modes > Remote notifications also added). The strange thing that it doesn't work only in the background.

ios: 10.2.1
nodejs: v7.7.1

"react": "^15.4.2", "react-native": "^0.42.0", "react-native-fcm": "^6.1.0",

does it work when app is closed?

on iOS it only works when I use the app, when the app is closed it doesn't

I was having the same issue and finally got it working. It turns out I didn't import the p12 certificate into Firebase and make sure it matches the provisioning profile in the app. None of the instructions really mention it very clearly, this is the closest I found. https://firebase.google.com/docs/cloud-messaging/ios/certs

@groke I did add my Production & Development APNs certificate to firebase :( any idea what I could do? for you everything is working under iOS also in the background?

have you tried the example in the repo?

@attilaaronnagy After I added my certificates to Firebase I created a new provisioning profile and loaded it into xcode so that it would include the APN certs I had just created. Not sure if that would affect your setup or not.

I'm with the same problem... notification just work with the app open or in the background, but when it's closed don't show nothing.

I did all the installation steps except this one:

In Xcode menu bar, select Product > Scheme > Manage schemes. Select your project name Scheme then click on the minus sign ― in the bottom left corner, then click on the plus sign + and rebuild your project scheme.

When I do this step my application stops compiling

testing on IPhone 5 and emulator

@LucasSouzaa emulator won't get push notification.

@evollu btw in iPhone 5 still don't getting notifications in foreground.

do I need put more configuration in AppDelegate.m or the configuration given in the tutorial are sufficient?

what is your iOS version? for IOS9 you won't get foreground notification.

OMG I'm feeling so stupid...
I was forgetting to put the certificate in the firebase console

I have the same issue as @attilaaronnagy
I included all certificates, created new ones and uploaded them, created a new provisioning profile, tried a production build

My AppDelegate.h

#import <UIKit/UIKit.h>
@import UserNotifications;

@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>
@property (nonatomic, strong) UIWindow *window;

@end

My AppDelegate.m

#import "AppDelegate.h"

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

#import "RNFIRMessaging.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

  NSURL *jsCodeLocation;

  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"EFGConnect"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  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];

  // ================ FCM =============================

 [FIRApp configure];
 [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];

  // ================================================


  return YES;
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
  [RNFIRMessaging willPresentNotification:notification withCompletionHandler:completionHandler];
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
{
  [RNFIRMessaging didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}

//You can skip this method if you don't want to use local notification
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
  [RNFIRMessaging didReceiveLocalNotification:notification];
}

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

app.js componentDidMount

componentDidMount(){

    FCM.requestPermissions(); // for iOS
    FCM.getFCMToken().then(token => {
        console.log('TOKEN: ',token)
    });

    this.notificationListener = FCM.on(FCMEvent.Notification, (notif) => {
      console.log( 'NOTIFICATION:', notif );

      if(notif.local_notification){
        // Alert.alert(notif.title, notif.message);
        //this is a local notification
      }
      if(notif.opened_from_tray){
        console.log('clicked on notification');
      }
      if(!notif.local_notification){
        FCM.presentLocalNotification({
          title: notif.title,
          body: notif.message,
          priority: "high",
          click_action: notif.click_action,
          show_in_foreground: true,
          local: true
        });
      }
    });
    this.refreshTokenListener = FCM.on(FCMEvent.RefreshToken, (token) => {
        SafeStorage.setItem('RegistrationID', ""+token).then(API.registerPushNotification)
    });
  },

I test by running

curl -X POST -H "Authorization: key=APP_KEY" -H "Content-Type: application/json" -d '
{
  "badge": 42,
  "priority" : "high",
  "content_available": true,
  "notification": {
    "title": "Background notification",
    "body": "ios notification",
    "icon": "new",
    "sound": "default"
  },
  "data": {
    "sound": "default",
    "title": "notification",
    "message": "ios notification",
    "category": "EXAMPLE_CATEGORY",
    "target": "ios"
  },
  "to" : "TOKEN_I_GET_FROM_LOG"

}' 'https://fcm.googleapis.com/fcm/send'

to no avail

Using "react-native-fcm": "^6.2.0", "react-native": "0.42",
Firebase from the sample app
OS IOS 10.2.1
XCode 8.2.1

__edit__ I tried setting up the sample app with my own FCM key and certificates and it worked, so now I'm gonna start comparing and see what happens

Sample app has
"react": "~15.4.0-rc.4",
"react-native": "^0.40.0",
"react-native-fcm": "^6.0.2"

but this doesn't seem like the reason, will inspect other things

__update__

So I tried matching the application implementation to no avail
I tried creating a new Friebase App
lowered the RNFCM version nothing

while downgrading to react to 0.40 downgrade I started removing cocopods and wound up breaking the app wile loading some libc* binaries

decided to there for go from the other side
renamed the bundle id of the sample app added to it the Google-service file and moved my app folder into the sample app

everything work

will save this version after a feature check then upgrade versions again to see if something breaks

same problem.

It works for me if I put "content_available: true" in "notification object", though different from the firebase doc.
For some reason, put it at the same level as "notification object", does not work for me.

Ref:
https://stackoverflow.com/a/38277476

e.g.

{
  "priority": "high",
  // "content_available": true, // <= not here
  "notification": {
     "body": "message",
     "sound": "default",
     "badge": 1,
     "content_available": true // <= here
  }
}

edit

I'm using fcm via Amazon SNS.
I wonder if that is the cause of this strange behavior.

Here's a good article I found that helped me. Background notifications work great now on iOS.

  1. Make sure Background fetch and Remote notifications Background Modes are enabled
  2. Make sure you haven't swiped away your app to kill it -- it sounds like no app can receive background notifications if it's been swiped away, just regular notifications
  3. Make sure you include content_available: true in the root of your payload
  4. The payload's aps dictionary must not contain the alert, sound, or badge keys [[source](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH10-SW8)]

@cooperka
point 2: You still can get notification, but notification callback won't be triggered.

So just to help the community... or confuse it if my experience is somehow misguided, ios throttles background notifications. I was thinking I could use these data messages to replace socket.io but turns out that is a dead end. I would sometimes get it right away, other times, would take 5 minutes. Don't rely on background notification times in ios. Use plain "notification" payloads if you really want to notify the user, otherwise, use something super lightweight like socket.io for real time when the user has the app open, then use background notifications for stuff like refreshing default data or profile data or something that is needed when you update your code and the default data isn't setup right for example.

@sebringj have you made sure finish is called to let iOS know you're using the notifications? Otherwise they will throttle them. But socket.io is probably a better solution regardless.

Aparently there must be some issue or particularity in the way that the fcm notification is sent
From the Google FCM Console it doesn't work but if I send a request to the fcm service through my own server it does

from my nodejs server:

request('https://fcm.googleapis.com/fcm/send', {
        headers: {
          "Content-Type": "application/json",
          "Authorization": "key=MYKEY"
        },
        method: 'POST',
        json: true,
        body: {
          "to": "MYTOKEN",
          "data": {
            "custom_notification": {
              "title": "Simple FCM Client",
              "body": "This is a notification with only NOTIFICATION.",
              "sound": "default",
              "priority": "high",
              "show_in_foreground": true
            }
          },
          "priority": 10
        }
      }, (error, response, body) => {
        if (error) {
          reject(error);
        } else {
          resolve({
            response: response,
            body: body
          });
        }
      });

When I send the notification this way everything works fine

I'm not sure if it has to do with the google fcm console or with notification body

same issue ;(

I fixed this problem. Forgot add [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self]; in AppDelegate.m problem is sloved

Was this page helpful?
0 / 5 - 0 ratings