Closed RRGT19 closed 2 years ago
Hi @RRGT19,
please try the following:
Prevent the auto initialization (see here) and call FirebaseMessaging.getToken()
in the ngOnInit
hook.
Does that help?
Hi @robingenz,
Thanks for your response.
I did what you say and now I receive the token. A weird thing is that I receive the same warning message but also I receive the token, Xcode logs:
⚡️ To Native -> FirebaseMessaging requestPermissions 53519772
⚡️ TO JS {"receive":"granted"}
⚡️ To Native -> FirebaseMessaging addListener 53519773
⚡️ To Native -> FirebaseMessaging addListener 53519774
⚡️ To Native -> FirebaseMessaging addListener 53519775
⚡️ To Native -> FirebaseMessaging subscribeToTopic 53519776
⚡️ To Native -> FirebaseMessaging getToken 53519777
⚡️ To Native -> FirebaseCrashlytics log 53519778
2022-06-16 08:29:59.607933-0400 App[89710:6301886] 9.1.0 - [FirebaseMessaging][I-FCM002022] APNS device token not set before retrieving FCM Token for Sender ID '707398199614'. Notifications to this FCM Token will not be delivered over APNS.Be sure to re-retrieve the FCM token once the APNS device token is set.
2022-06-16 08:29:59.610659-0400 App[89710:6301886] 9.1.0 - [FirebaseMessaging][I-FCM002022] APNS device token not set before retrieving FCM Token for Sender ID '707398199614'. Notifications to this FCM Token will not be delivered over APNS.Be sure to re-retrieve the FCM token once the APNS device token is set.
⚡️ TO JS undefined
⚡️ TO JS {"token":"cbodk8c-IEKaj2nDG_8xzm:APA9....................."}
⚡️ TO JS {"token":"cbodk8c-IEKaj2nDG_8xzm:APA9....................."}
⚡️ [log] - tokenReceived cbodk8c-IEKaj2nDG_8xzm:APA9..............
⚡️ TO JS {"token":"��w����,\u0015\u0007�X��u����<u-��\\��UT#�|"}
⚡️ [log] - tokenReceived ��w����,�X��u����<u-��\��UT#�|
⚡️ TO JS undefined
⚡️ [log] - Subscribed to topic example
I have a few questions though:
getToken()
has a required parameter called options, I needed to pass null.FirebaseMessaging.getToken(null).then(res => {
console.log('getToken', res.token);
const token = res.token;
})
I think the parameter should be optional, as the doc says, the parameters are meant to be used on Web. Example:
getToken(options?: GetTokenOptions): Promise<GetTokenResult>;
(Notice the question mark)
If I need to do this on Android too:
The doc says that also the collection should be disabled, see here.
How can we enable again the analytics collection? maybe it's enabled automatically after a token is generated? I think this point is not too clear to me.
The Google docs says that we need to re-enable FCM auto-init, see here. I don't see a method within the library to do this. iOS also has this requirement, see here.
getToken()
and inside of addListener('tokenReceived'.....)
. Which one should I keep?
Maybe the implementation should be to call getToken without .then()
? Example:await FirebaseMessaging.getToken(null);
// Here I get the token for iOS and Android.
FirebaseMessaging.addListener('tokenReceived', event => {
console.log('tokenReceived', event.token);
});
import {Injectable, NgZone} from '@angular/core';
import {FirebaseMessaging} from '@capacitor-firebase/messaging';
import PlatformUtil from '../../shared/utilities/PlatformUtil';
@Injectable()
export class PushNotificationService {
constructor(
private ngZone: NgZone
) {
}
init() {
if (PlatformUtil.isMobile) {
this.requestPermissions();
}
}
private requestPermissions(): void {
FirebaseMessaging.requestPermissions().then(result => {
if (result.receive === 'granted') {
this.addListeners();
// Here, only for iOS
if (PlatformUtil.isIos) {
this.getToken();
}
} else {
// Show some error
}
});
}
private getToken(): void {
FirebaseMessaging.getToken(null).then(res => {
console.log('getToken', res.token);
const token = res.token;
})
}
private addListeners(): void {
// Called when a new FCM token is received.
FirebaseMessaging.addListener('tokenReceived', event => {
console.log('tokenReceived', event.token);
});
// Called when a new push notification is received.
FirebaseMessaging.addListener('notificationReceived', event => {
console.log('notificationReceived', {event});
});
// Called when a new push notification action is performed.
FirebaseMessaging.addListener('notificationActionPerformed', event => {
console.log('notificationActionPerformed', {event});
});
}
}
This is correct?
checkPermissions()
return granted. Thanks again for your help, just trying to understand the correct way to do this.
getToken() has a required parameter called options, I needed to pass null.
You need to pass a empty object {}
. null
is not a valid value (see typescript defintions). But yes, this param could be optional.
Do I need to prevent the auto initialization on Android too?
Prevent the auto initialization is optional. You can use it (for privacy reasons for example) but you don't have to.
What happens on iOS if you don't use it but call getToken
anyway? The warning should still appear, but everything should work.
But for now you can use my workaround.
How can we enable again the analytics collection? maybe it's enabled automatically after a token is generated? I think this point is not too clear to me.
Call setEnabled.
The Google docs says that we need to re-enable FCM auto-init, see here. I don't see a method within the library to do this. iOS also has this requirement, see here.
Just call getToken
to re-enable it.
After testing your advice, I have received the same token in different places, inside of getToken() and inside of addListener('tokenReceived'.....). Which one should I keep?
It should be the same token, so it doesn't matter where you take it from.
I see that to fix my issue I need to call getToken only for iOS, that means that I need to handle this scenario depending on the platform? check my complete implementation:
Just call getToken
on every platform as soon as everything is ready to receive push notification.
You should call this on every startup anyway to check if the FCM token has changed. Your backend should always know the latest token of a user.
The listeners are okay there or do I need to register them inside the constructor to be called every time the App is started? If the App gets killed, I think the listeners are cleared. I'm not sure if the listeners should be set again when the App starts, for example, if checkPermissions() return granted.
You have to register the listeners at every app start.
Thanks again for your help, just trying to understand the correct way to do this.
No problem, you're welcome!
@robingenz awesome explanation thank you!.
Just a few questions:
About the setEnabled, I didn't know it was in another library. Maybe a little mention on the doc of the Cloud Messaging library should be okay?
Before calling getToken
and listeners on every startup, the best practice is to check if the user has granted permission using checkPermissions() ? otherwise, I think I will be initializing listeners and subscribing to topics without knowing if the user has given his permission before.
All your advice helped me and now I'm more confident that my implementation is more correct. I think after this, this thread can be closed. :innocent:
About the setEnabled, I didn't know it was in another library. Maybe a little mention on the doc of the Cloud Messaging library should be okay?
I'm going to rewrite and unify the setEnabled methods anyway, so that should be more obvious soon (see #13).
Before calling getToken and listeners on every startup, the best practice is to check if the user has granted permission using checkPermissions() ?
Right. First request permissions, then retrieve FCM token.
Thanks again for your issue. This helps me to improve this library. 👍
I'm leaving the issue open yet as I want to debug the ios issue before closing it.
Plugin(s):
Docs: https://github.com/robingenz/capacitor-firebase/tree/main/packages/messaging
Platform(s): iOS
Current behavior: When I request the permission, I see in Xcode console:
Expected behavior: No warnings and a token provided.
Steps to reproduce:
Related code: AppDelegate:
My Ionic Service to handle Push Notification and Token logic:
Capacitor doctor:
Any help is appreciated.