Closed naorzr closed 5 years ago
I have seen the same issue. I was able to get the APNs token only on first launch though.
@nigel-smk the first launch of the app? cause I didn't managed to even make that happen
@naorzr I think I have solved this.
I found this issue for a competing library that had the same issue
I don't understand it entirely but it seems that we need to registerForRemoteNotifications first.
The react-native-firebase
messaging reference docs are currently broken. But if we dig into the docs in the repo we find that react-native-firebase
has the registerForRemoteNotifications
method as well.
This reliably got me the APNs Token:
firebase.messaging().ios.registerForRemoteNotifications().then(() => {
firebase.messaging().ios.getAPNSToken().then(token => {
// token not null
});
})
While this did not:
firebase.messaging().ios.getAPNSToken().then(token => {
// token always null
});
Based on my reading of the solution to https://github.com/evollu/react-native-fcm/issues/510 I think that this issue is a bug with react-native-firebase
@nigel-smk thanks for taking your time with the comment though I have done it, and still getting null..(as written in the original post) is the token not being null behaviour persistent for you?
@naorzr Are you using a real device? The simulator will never get and APNs token
When running on a real device I get the above described behaviour every time. I have switched between the two appraoches 3-4 times now and without the register call I always get null.
@nigel-smk yea I am
@nigel-smk any chance you could please post here your AppDelegate.m and Podfile? Can't get this to work no matter what, reinstalled and refollowed the tutorials over and over.
well in the end i've reinstalled, reconfiged everything from scratch and it was resolved.
I'm having the same issue
Add this function to AppDelegate.m:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[FIRMessaging messaging].APNSToken = deviceToken;
}
Hope this will be helpful.
I was having the same issue for days and nothing from the above helped, but I got it working myself.
I just added this to didFinishLaunchingWithOptions
method in AppDelegate.m
:
[[UIApplication sharedApplication] registerForRemoteNotifications];
This is kind of strange, but for me this was behavior on ios device:
console.log(await firebase.messaging().hasPermission()) // false
console.log(await firebase.messaging().getToken()) // got FCM token
console.log(await firebase.messaging().ios.getAPNSToken()) // null
When I requested permissions:
console.log(await firebase.messaging().hasPermission()) // false
console.log(await firebase.messaging().requestPermission()) // allow on popup
console.log(await firebase.messaging().getToken()) // got FCM token
console.log(await firebase.messaging().ios.getAPNSToken()) // got APNS token
So also try to check permissions 😄 It is kind of weird that you will get FCM token but no APNS I would expect the same behavior for both
The point here seems to be that even if method hasPermission() returns true, you need to call requestPermission() in order to get the APNS token
I was running into this issue despite trying everything above until just recently.
Turns out my GoogleService-Info.plist
file was not correctly added to my ios
project folder. Once I added it at the same level as AppDelegate.m
in XCode firebase.messaging().ios.getAPNSToken()
returned an actual APNS token instead of null
.
This helped me get the APNS token:
firebase
.messaging()
.ios.registerForRemoteNotifications()
.then(() => {
console.log('REGISTER FOR REMOTE NOTIFICATIONS');
firebase
.messaging()
.ios.getAPNSToken()
.then(token => {
console.log(
'APNS TOKEN AFTER REGISTRATION FOR BACKGROUND',
token,
);
});
});
In my case, calling ios.registerForRemoteNotifications() in release build:
firebase.messaging().ios.registerForRemoteNotifications().then(() => {
firebase.messaging().ios.getAPNSToken().then((apnsToken) => {
console.log(apnsToken)
})
})
apnsToken sometime null, is this normal behavior?
I was having the same issue for days and nothing from the above helped, but I got it working myself. I just added this to
didFinishLaunchingWithOptions
method inAppDelegate.m
:
[[UIApplication sharedApplication] registerForRemoteNotifications];
This really helped me! Thank you so much buddy!
Even using registerForRemoteNotifications
before calling getAPNSToken
I get null the first time after the app launches.
await firebase.messaging().ios.registerForRemoteNotifications();
const apnsToken = await firebase.messaging().ios.getAPNSToken();
apnsToken === null
Then when calling getAPNSToken
again later, it correctly returns the token.
I'm suspecting that the promise returned from registerForRemoteNotifications
does not wait for the token to be registered before resolving, so I think it shouldn't be returning a promise at all.
I think adding a registerForRemoteNotifications
or didRegisterForRemoteNotificationsWithDeviceToken
in AppDelegate.m
is not a solid solution because it may still cause a race condition where the token has not been registered before getAPNSToken
is called. (if registering for token takes longer than the JS code takes to call getAPNSToken
). This is probably why people are seeing that it works sometimes and other times not.
Although very hacky, this seems to work and will never return null:
async function getAPNSToken() {
while (true) {
const apnsToken = await firebase.messaging().ios.getAPNSToken();
if (apnsToken !== null) return apnsToken;
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
await firebase.messaging().ios.registerForRemoteNotifications();
const apnsToken = await getAPNSToken();
Add this function to AppDelegate.m:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [FIRMessaging messaging].APNSToken = deviceToken; }
Hope this will be helpful.
Many thanks, you saved my day!
Hi,
I used firebase to get device token but always return null :
askNotificationPermission(){
if (this.platform.is('cordova') && this.platform.is('ios')) {
this.firebase.grantPermission().then(function(hasPermission){
console.log("Permission was " + (hasPermission ? "granted" : "denied"));
}).finally(()=>{
this.firebase.onApnsTokenReceived()
.subscribe(token => {
const deviceData = {
reg_id: token,
os: this.device.platform
};
this.services.device_data = deviceData;
localStorage.setItem('deviceData', JSON.stringify(deviceData));
})})}}
this is my code in ionic application
I was having the same issue for days and nothing from the above helped, but I got it working myself. I just added this to
didFinishLaunchingWithOptions
method inAppDelegate.m
:
[[UIApplication sharedApplication] registerForRemoteNotifications];
I have no idea why, but this also solved my issue. The strange thing is, I did not changed anything in my project. But I believe it happened right after I implemented react-native-splash-screen.
My AppDelegate file was changed from this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
self.moduleName = @"Gardrows";
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
To this after RN Splash Screen:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
self.moduleName = @"Gardrows";
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
bool didFinish = [super application:application didFinishLaunchingWithOptions:launchOptions];
[RNSplashScreen show];
return didFinish;
}
I believe somehow I messed with Firebase initial configuration by changing return of the function even though the type and value checks out.
Now the successful solution of the AppDelegate goes like:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
[[UIApplication sharedApplication] registerForRemoteNotifications];
self.moduleName = @"Gardrows";
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
bool didFinish = [super application:application didFinishLaunchingWithOptions:launchOptions];
[RNSplashScreen show];
return didFinish;
}
Issue
On the server side we are using amazon sns service for the fcm communication with the devices, so the token returned from
firebase.messaging().getToken()
is just too long. So we've figured we should get the token with getAPNStoken callonly that this call returns null no matter what I try, the documentation isn't very clear about how to use and use cases, but I guess that it should be inferred from the name. anyhow, I've also tried to register first using
still no success. Am I doing something wrong, or is that a bug?
Project Files
iOS
ios/Podfile
:AppDelegate.m
:Environment
ADD_SOMETHING_HERE
e.g. iOS 10 or Android API 28N/A
N/A
N/A
React Native
version:0.57.3
React Native Firebase
library version:5.2.3
Firebase
module(s) you're using that has the issue:TypeScript
?N/A
ExpoKit
?ExpoKit