I'm using the Firebase Javascript SDK to add web push notifications to a React JS app. Through some sequence of events, we've wound up with two FCM tokens that appear to be from the same web client (same machine, browser and site domain). An FCM message sent to either token is received on the client. I would have expected one of the tokens to get invalidated, but that doesn't seem to be the case. Is it possible to identify and delete the extraneous token when this situation occurs?
The code to register our service worker and send the FCM token to our backend service looks like this:
firebase.initializeApp(Config.firebase);
this.messaging = firebase.messaging();
this.setupNotifications(this.messaging, this.loadAlerts.bind(this));
setupNotifications(messaging, handler) {
let _this = this;
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw/firebase-messaging-sw.js')
.then(function(registration) {
registration.update();
_this.messaging.useServiceWorker(registration);
Notification.requestPermission().then(messaging.requestPermission)
.then(function (t) {
return messaging.getToken();
})
.then(function (token) {
// This saves the token to our server
Service.register(token);
})
.catch(function (error) {
console.log('Error occured: ' + error.message)
});
}).catch(e => {
console.log('Error during firebase registration: ' + e.message);
});
navigator.serviceWorker.addEventListener('message', event => {
if (event.data.incidents) {
// If the event data contains an incidents property, then this is a message from our
// service worker notification click handlers. Load details for the incidents.
window.location = some_url_path + event.data.incidents;
}
});
_this.messaging.onMessage(function (payload) {
handler();
});
_this.messaging.onTokenRefresh(function() {
messaging.getToken()
.then(function(refreshedToken) {
// This saves the refreshed token to our server
Service.register(refreshedToken);
})
.catch(function(err) {
console.log('Unable to retrieve refreshed token ', err);
});
});
}
}
A few (possibly) relevant points:
- The web client had an active FCM token for some time (weeks). The new token was generated at some point, but now
messaging.getToken()
is returning the previous token. - Around the time the second token was generated, we had (mistakenly) changed the path to the service worker script that we pass to
navigator.serviceWorker.register()
. This appears to have resulted in two registered service workers (as seen in Chrome Developer Tools), but unregistering the worker with incorrect path had no effect. - Also around the same time we updated from the Firebase library we were using from 3.9.0 to 4.6.2
- Through Chrome Developer tools, I can see there are two IndexedDBs, and one of them has an fcm_token_object_Store with the extraneous token, which is different than the token returned by
messaging.getToken()
displayed in the console output in the image below:
However it happened that these two FCM tokens got created, what my primary concern is how to get rid of one of them. Is there some way to get all active FCM tokens for a client instance so we could call messaging.deleteToken()
on the extraneous one? It was only by fluke I was able to identify the two tokens in question on a machine I could debug on, so if this happens for a real end-user, I'm not sure how we'd correct the situation.