My apns token is always null (on device) and as a result I never receive notification while my app is in the background on iOS.
I'm migrating from react-native-fcm. setBadge works, getting an FCM token works, onMessage works, and everything works on Android.
I've tried every combination of registering, configuring, etc, based off of all of the other issues I've seen related to this. The capabilities are on, and I tried turning them off and on again as well. These issues do carry over to my new repo made for testing this issue.
What I'm experiencing instead is a null apns token. I believe that's the main reason I'm not receiving these notifications. I am registering first, then trying to get the token second, as I've seen in other people's issues.
When I try using postman to post to https://fcm.googleapis.com/fcm/send
I get back a successful response. My project is configured on Firebase with an APNs Auth Key.
Yes, "FirebaseAppDelegateProxyEnabled" is not set to "NO" in my Info.plist
Yes, I'm not trying in the simulator.
Yes, the APNS keys appear active on Apple's developer site.
Yes, I am very up to date on all of my libraries.
Yes, I have tried react-native clean-project
.
Yes, I am prompted if I want to receive notifications.
Yes, I accept it.
Yes, everything looks good from notification settings.
https://github.com/theminery-hr4/firebasetest
I've excluded my GoogleService-Info.plist from this repo, but it exists during my testing.
Key files are Firebase.js, AppDelegate.m. Pretty much everything else is default react native.
AppDelegate.m
:@import Firebase;
#import "RNFirebaseNotifications.h"
#import "RNFirebaseMessaging.h"
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>
#if RCT_DEV
#import <React/RCTDevLoadingView.h>
#endif
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
[RNFirebaseNotifications configure];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
#if RCT_DEV
[bridge moduleForClass:[RCTDevLoadingView class]];
#endif
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"FirebaseTest"
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];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[[RNFirebaseNotifications instance] didReceiveLocalNotification:notification];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings];
}
@end
Firebase.js
:import React, { Component } from 'react'
import { SafeAreaView, Text, Alert, AppState } from 'react-native'
import firebase from 'react-native-firebase'
export default class Firebase extends Component {
checkPermission = async () => {
let enabled = false
try {
await firebase.messaging().requestPermission()
enabled = await firebase.messaging().hasPermission()
enabled && this.getFcmToken()
} catch(error) {
this.showAlert('checkPermission', 'checkPermission error')
}
}
getFcmToken = async () => {
const fcmToken = await firebase.messaging().getToken()
if(fcmToken) {
//this.showAlert('getFcmToken', 'fcmToken '+fcmToken)
firebase.messaging().ios.registerForRemoteNotifications().then(() => {
firebase.messaging().ios.getAPNSToken().then(apns => {
this.showAlert('getFcmToken', 'apns: '+apns)
}).catch((e) => {
this.showAlert('getFcmToken', 'apns error')
})
})
} else {
this.showAlert('getFcmToken', 'fcm token is falsey')
}
}
handleNotification = (notification) => {
if(!notification) {
return
}
if(notification.notification) {
notification = notification.notification
}
const data = notification.data || notification
const { type } = data
if(!type) {
return
}
this.showAlert('handleNotification', 'type: '+type)
}
componentDidMount() {
this.showAlert('componentDidMount', 'didMount')
this.checkPermission()
firebase.notifications().getInitialNotification().then(this.handleNotification)
firebase.notifications().onNotificationOpened(this.handleNotification)
firebase.notifications().onNotification(this.handleNotification)
firebase.messaging().onMessage(this.handleNotification)
AppState.addEventListener('change', (appState) => {
appState === 'active' && this.checkPermission()
})
}
showAlert = (title, message) => {
Alert.alert(
title,
message,
[
{text: 'OK', onPress: () => {}},
],
{cancelable: false},
);
}
render() {
return (
<SafeAreaView style={{flex: 1}}>
<Text style={{flex: 1}}>Firebase Test</Text>
</SafeAreaView>
)
}
}
ios/Podfile
:platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
target 'FirebaseTest' do
# Pods for FirebaseTest
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'
pod 'Firebase/Core'
pod 'Firebase/Messaging'
target 'FirebaseTestTests' do
inherit! :search_paths
# Pods for testing
end
use_native_modules!
end
target 'FirebaseTest-tvOS' do
# Pods for FirebaseTest-tvOS
target 'FirebaseTest-tvOSTests' do
inherit! :search_paths
# Pods for testing
end
end
macOS 10.15.1
Xcode 11.2.1
Node 10.17.0
Yarn 1.19.1
React Native 0.61.5
React 16.9.0
React Native Firebase 5.6.0
Firebase Core 6.13.0
iPhone 5 running iOS 10.3.3
Interesting thread here with suggested workarounds: https://github.com/invertase/react-native-firebase/issues/2657#issuecomment-549181244 also a workaround mentioned is to do a wait for a couple seconds before fetching token to handle something inherently async/network-related about token generation
Despite having no luck on my device, I decided to push my latest code to TestFlight and it works for my coworker, so I think my issue is just device specific.
Thank you for the link. I hadn't seen this one, and while I think it's more specific to the version 6 plugin, it gave me some more things to try, none of which were able to help with my problem though.
For anyone that may be having the same issue. I went through a million fixes and realize finally that I did not have the aps-entitlements
on for debug mode.
The Push Notifications
were allowed in Release and not in Debug.
@theminerymike How did you fix it? I have a same issue. didRegisterForRemoteNotifications
not called even call registerForRemoteNotifications
. So cannot get APNS token and it cause remote notificatoin not work. I am testing in 6.4.0-rc4
It works after using cellular with usim. I checked https://support.apple.com/en-us/HT203609.
@JeffGuKang I also faced the same issue . After I switched to wifi connection it works
v6.7.1 Still get null
when called getAPNSToken
I am experiencing this issue.
Me as well, v6.4.0 still get null on getAPNSToken
.
On production build it works the first time. If you close the app however, and open it again, apns is null
registerForRemoteNotifications
is not works on debug + Wi-Fi environment sometimes. I think it is a issue related to iOS
. not react-native-firebase/messaging
We can check the codes through break point on XCode.
RNFBMessagingModule.m
RCT_EXPORT_METHOD(registerForRemoteNotifications:
(RCTPromiseResolveBlock) resolve
: (RCTPromiseRejectBlock) reject
) {
#if TARGET_IPHONE_SIMULATOR
resolve(@([RCTConvert BOOL:@(YES)]));
return;
#endif
if (@available(iOS 10.0, *)) {
if ([UIApplication sharedApplication].isRegisteredForRemoteNotifications == YES) {
resolve(@([RCTConvert BOOL:@(YES)]));
} else {
[[RNFBMessagingAppDelegate sharedInstance] setPromiseResolve:resolve andPromiseReject:reject];
}
// Apple docs recommend that registerForRemoteNotifications is always called on app start regardless of current status
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications]; // THIS
});
} else {
[RNFBSharedUtils rejectPromiseWithUserInfo:reject userInfo:[@{
@"code": @"unsupported-platform-version",
@"message": @"registerDeviceForRemoteMessages call failed; minimum supported version requirement not met (iOS 10)."} mutableCopy]];
}
}
RNFBMessaging+AppDelegata.m
Sometimes this code is never called.
And this makes APNSToken
null.
// called when `registerForRemoteNotifications` completes successfully
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
#ifdef DEBUG
[[FIRMessaging messaging] setAPNSToken:deviceToken type:FIRMessagingAPNSTokenTypeSandbox];
#else
[[FIRMessaging messaging] setAPNSToken:deviceToken type:FIRMessagingAPNSTokenTypeProd];
#endif
if (_registerPromiseResolver != nil) {
_registerPromiseResolver(@([RCTConvert BOOL:@([UIApplication sharedApplication].isRegisteredForRemoteNotifications)]));
_registerPromiseResolver = nil;
_registerPromiseRejecter = nil;
}
}
Apologies for jumping on this closed ticket, but I'm having this issue on my devices. I have two iOS test devices I'm using. Yesterday, my primary device was working perfectly. It would give me the APNS token and notifications were appearing. Today, it's not giving me the token and notifications have stopped working on that device.
The _exact_ same code is running on my second test device and is working perfectly, as expected.
Why would it suddenly stop working on one device overnight?
If anyone out there can help, I'm running out of hair to pull out!
Update: after trying every trick under the sun that's been suggested, I finally gave up and followed the age-old IT support desk advice. I turned it off and turned it back on again.
Now it's working.
Slightly nervous that this is what fixed it, but will monitor if it happens again more closely.
Most helpful comment
Apologies for jumping on this closed ticket, but I'm having this issue on my devices. I have two iOS test devices I'm using. Yesterday, my primary device was working perfectly. It would give me the APNS token and notifications were appearing. Today, it's not giving me the token and notifications have stopped working on that device.
The _exact_ same code is running on my second test device and is working perfectly, as expected.
Why would it suddenly stop working on one device overnight?
If anyone out there can help, I'm running out of hair to pull out!
Update: after trying every trick under the sun that's been suggested, I finally gave up and followed the age-old IT support desk advice. I turned it off and turned it back on again.
Now it's working.
Slightly nervous that this is what fixed it, but will monitor if it happens again more closely.