React-native-firebase: iOS background remote notification with FCM not appearing

Created on 20 Apr 2020  路  5Comments  路  Source: invertase/react-native-firebase


Issue



Real iOS device, 13.3.1, iPhone 11
Sending a test push notification with https://console.firebase.google.com/u/0/project/_/notification/compose to device.

Message received when app is in foreground. No push notification banner appears when app is in background.

Initialization code is as follows

const App = ()=>{

useEffect(() => {
    async function requestUserPermission() {
      const settings = await messaging().requestPermission();
      if (settings) {
        console.log("Permission settings:", settings);
      }
    }
    const init = async () => {
      console.log("Initializing remote messaging.");
      await messaging().registerDeviceForRemoteMessages();
      console.log("Registered device with FCM.");
      await requestUserPermission();
      console.log("Requested user permission.");
      const fcmToken = await firebase.messaging().getToken();
      console.log(`fcmToken: ${fcmToken}`);
      const apnsToken = await firebase.messaging().getAPNSToken();
      console.log(`apnsToken: ${apnsToken}`);
    };
    init();
  }, []);
  useEffect(() => {
    const unsubscribe = messaging().onMessage(async (remoteMessage) => {
      console.log("A new FCM message arrived!", JSON.stringify(remoteMessage));
    });

    return () => {
      unsubscribe();
    };
  }, []);
....
}

Documentation was followed to a T.
https://rnfirebase.io/messaging/usage
iOS instructions also followed
https://rnfirebase.io/messaging/usage/ios-setup

  • App capability configured
  • Key generated and uploaded to Firebase
  • App identifier + provisioning profile automatically generated -- I also tried manually creating this but no difference.

Issues I've seen online:
https://github.com/invertase/react-native-firebase/issues/3069

  • Useless since #import "RNFirebaseNotifications.h"

import "RNFirebaseMessaging.h" are deprecated/gone I think

https://github.com/invertase/react-native-firebase/issues/3067

  • Useless since a fix was issued which doesn't fix the issue

Not sure whats going wrong. Any help is appreciated.

Also tried turning method sizzling off by setting the delgate proxy to NO in Info.plist, then setting it manually in AppDelegate.m. NOt sure if this is working since I don't think printf statements from the Xcode project show up in Metro bundler output.


Project Files






Javascript

Click To Expand

#### `package.json`:

{
  "name": "CoDrop",
  "version": "6.4.0",
  "private": true,
  "scripts": {
    "start": "react-native start",
    "run:android": "react-native run-android",
    "run:ios": "react-native run-ios --simulator=\"iPhone X\"",
    "build:apk": "cd android && ./gradlew assembleRelease",
    "test": "jest",
    "prepare": "patch-package"
  },
  "dependencies": {
    "@ant-design/react-native": "^3.3.0",
    "@react-native-community/async-storage": "^1.9.0",
    "@react-native-community/google-signin": "^4.0.0",
    "@react-native-community/masked-view": "^0.1.7",
    "@react-native-firebase/app": "^6.4.0",
    "@react-native-firebase/auth": "^6.4.0",
    "@react-native-firebase/firestore": "^6.4.0",
    "@react-native-firebase/messaging": "^6.4.0",
    "@react-native-firebase/storage": "^6.4.0",
    "@react-navigation/bottom-tabs": "^5.2.5",
    "@react-navigation/native": "^5.1.4",
    "@react-navigation/stack": "^5.2.9",
    "moment": "^2.24.0",
    "react": "16.9.0",
    "react-native": "0.61.5",
    "react-native-fast-image": "^8.1.5",
    "react-native-feather1s": "^0.2.2",
    "react-native-gesture-handler": "^1.6.1",
    "react-native-get-random-values": "^1.3.1",
    "react-native-image-picker": "^2.3.1",
    "react-native-modal": "^11.5.6",
    "react-native-reanimated": "^1.8.0",
    "react-native-safe-area-context": "^0.7.3",
    "react-native-screens": "^2.4.0",
    "react-native-search-bar": "^3.5.1",
    "react-native-swipe-gestures": "^1.0.5",
    "react-native-uuid": "^1.4.9",
    "react-native-uuid-generator": "^6.1.1",
    "react-native-vector-icons": "^6.6.0",
    "react-native-view-shot": "^3.1.2",
    "uuid": "^7.0.3"
  },
  "devDependencies": {
    "@babel/core": "^7.6.2",
    "@babel/runtime": "^7.6.2",
    "@react-native-community/cli": "^2.9.0",
    "@react-native-community/eslint-config": "^0.0.5",
    "babel-jest": "^24.9.0",
    "eslint": "^6.5.1",
    "jest": "^24.9.0",
    "metro-react-native-babel-preset": "^0.56.0",
    "patch-package": "^6.1.4",
    "react-test-renderer": "16.9.0"
  },
  "jest": {
    "preset": "react-native"
  }
}
#### `firebase.json` for react-native-firebase v6:
{
  "react-native": {}
}
### iOS
Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like:

platform :ios, '10.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

# To override the React Native Firebase iOS SDK versions used uncomment any of the below and change the version
# $FirebaseSDKVersion = '6.8.1'
# $FabricSDKVersion = '1.6.0'
# $CrashlyticsSDKVersion = '3.1.0'

# To use RNFirebase packages as static frameworks uncomment the below line
# $RNFirebaseAsStaticFramework = true

target 'CoDrop' do
  # Pods for CoDrop
  pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
  pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
  pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
  pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/'
  pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
  pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
  pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
  pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
  pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
  pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'


  target 'CoDropTests' do
    inherit! :search_paths
    # Pods for testing
  end

  use_native_modules!
end

target 'CoDrop-tvOS' do
  # Pods for CoDrop-tvOS

  target 'CoDrop-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end

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

#import "AppDelegate.h"
#import <Firebase.h>


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

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  if ([FIRApp defaultApp] == nil) {
    [FIRApp configure];
  }
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"CoDrop"
                                            initialProperties:nil];

  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];

  [FIRMessaging messaging].delegate = self;
  [application registerForRemoteNotifications];
  [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
  printf("Fuck me");

  return YES;
}

- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken
{

}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  printf("Registered for remote notifications.");
  [FIRMessaging messaging].APNSToken = deviceToken;
}

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

@end


Android

Click To Expand

#### Have you converted to AndroidX? - [ ] my application is an AndroidX application? - [ ] I am using `android/gradle.settings` `jetifier=true` for Android compatibility? - [ ] I am using the NPM package `jetifier` for react-native compatibility? #### `android/build.gradle`:

// N/A
#### `android/app/build.gradle`:
// N/A
#### `android/settings.gradle`:
// N/A
#### `MainApplication.java`:
// N/A
#### `AndroidManifest.xml`:
<!-- N/A -->


Environment

Click To Expand

**`react-native info` output:**

npx react-native info
info Fetching system and libraries information...
System:
    OS: macOS 10.15
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 104.70 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.6.0 - /usr/local/bin/node
    Yarn: 1.17.3 - /usr/local/bin/yarn
    npm: 6.13.7 - /usr/local/bin/npm
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
  IDEs:
    Xcode: 11.2.1/11B53 - /usr/bin/xcodebuild
  npmPackages:
    @react-native-community/cli: ^2.9.0 => 2.10.0
    react: 16.9.0 => 16.9.0
    react-native: 0.61.5 => 0.61.5
 OUTPUT GOES HERE
- **Platform that you're experiencing the issue on**: - [ x] iOS - [ ] Android - [x ] **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:** 6.4.0 - **`Firebase` module(s) you're using that has the issue:** Messaging - **Are you using `TypeScript`?** - `Y/N` & `VERSION` N




Most helpful comment

Got this to work by magic

For future people:
1.add this AppDelegate.m to

[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];

I found this in some other other StackOverflow answer

  1. turn off method swizling
    set FirebaseAppDelegateProxyEnabled to NO in Xcode info.plist

  2. manually assign the apns tokenin appdelegate.m

  3. (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
    [FIRMessaging messaging].APNSToken = deviceToken;
    }

some required improts in appdelegate.m

import

import

here's what appdelegate.h looks like

import

import

import

@import UserNotifications;

@interface AppDelegate : UIResponder
//@interface AppDelegate : UIResponder

@property (nonatomic, strong) UIWindow *window;

@end

Hope this helps somebody in the future

90% of time probably issue with apns + tokens/certs

All 5 comments

Just did some more checks with breakpoints and both
didRegisterForRemoteNotificationsWithDeviceToken:
and
didFailToRegisterForRemoteNotificationsWithError

aren't being called at all --
seems like
await messaging().registerDeviceForRemoteMessages();

is only doing the fcm token since - (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken
{
RCTLog(@"Received registration token");

}
is being called.

Got this to work by magic

For future people:
1.add this AppDelegate.m to

[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];

I found this in some other other StackOverflow answer

  1. turn off method swizling
    set FirebaseAppDelegateProxyEnabled to NO in Xcode info.plist

  2. manually assign the apns tokenin appdelegate.m

  3. (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
    [FIRMessaging messaging].APNSToken = deviceToken;
    }

some required improts in appdelegate.m

import

import

here's what appdelegate.h looks like

import

import

import

@import UserNotifications;

@interface AppDelegate : UIResponder
//@interface AppDelegate : UIResponder

@property (nonatomic, strong) UIWindow *window;

@end

Hope this helps somebody in the future

90% of time probably issue with apns + tokens/certs

@bryanhpchiang I'm getting the same issue that you had. can you post your AppDelegate.m? or specify exactly where to add the content in step 1?

Got this to work by magic

For future people:
1.add this AppDelegate.m to

[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];

I found this in some other other StackOverflow answer

  1. turn off method swizling
    set FirebaseAppDelegateProxyEnabled to NO in Xcode info.plist
  2. manually assign the apns tokenin appdelegate.m
  • (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
    [FIRMessaging messaging].APNSToken = deviceToken;
    }

some required improts in appdelegate.m

import

import

here's what appdelegate.h looks like

import

import

import

@import UserNotifications;

@interface AppDelegate : UIResponder
//@interface AppDelegate : UIResponder

@Property (nonatomic, strong) UIWindow *window;

@EnD

Hope this helps somebody in the future

90% of time probably issue with apns + tokens/certs

SO MUCH LOVE @bryanhpchiang

Depending on your FCM Server SDK that you are using, you might also need to ensure that the call to FCM API endpoint includes the new apns-push-type header.

var message = {
  "tokens": tokensArray,
  "data": {
    "info":"someInfo"
  },
  "apns": {
    "headers": {
      "apns-push-type": "alert",
      "apns-priority": "5"
    },
    "payload": {
      "aps":{
        "contentAvailable": true
      }
    }
  }
};
Was this page helpful?
0 / 5 - 0 ratings