Skip to content

Instantly share code, notes, and snippets.

@vibgy
Last active January 20, 2022 16:08
Show Gist options
  • Save vibgy/0c5f51a8c5756a5c408da214da5aa7b0 to your computer and use it in GitHub Desktop.
Save vibgy/0c5f51a8c5756a5c408da214da5aa7b0 to your computer and use it in GitHub Desktop.
Angular Service and Service Worker Code to handle FCM data messages and to enable a click handler for notifications shown using showNotification
//
// serviceWorkerService.js
//
'use strict';
angular.module('myApp.serviceWorker', [])
.service('serviceWorkerService', ['$q', '$http', '$location', '$timeout',
function($q, $http, $location, $timeout) {
var noTokenError = new Error('No Instance ID token available');
var noPermissionError = new Error('Unable to get permission to notify');
this.messaging = firebase.messaging();
this.unsubscribe = null;
this.unsubscribeTokenRefresh = null;
this.registerWorkerPromise = null;
this.tokenPermissionPromise = null;
this.registerWorker = function () {
return this.getRegistration();
};
this.setUpHandlers = function (onTokenRefresh, onMessage) {
// Callback fired if Instance ID token is updated.
var self = this;
this.unsubscribeTokenRefresh = this.messaging.onTokenRefresh(function() {
// token just refreshed, lets delete our saved Promise
delete self.tokenPermissionPromise;
self.getSubscription()
.then(function(refreshedToken) {
console.log('Token refreshed.');
onTokenRefresh(refreshedToken);
})
.catch(function(err) {
console.log('Unable to retrieve refreshed token ', err);
});
});
this.unsubscribeMessages = this.messaging.onMessage(function(payload) {
console.log("Message received. ", payload);
onMessage(payload);
});
}
this.subscribe = function (onUI, onLog, onToken, onMessage) {
var deferred = $q.defer();
var self = this;
onUI = onUI || function() {};
onLog = onLog || console.log;
onToken = onToken || function() {};
onMessage = onMessage || function() {};
// we dont want to cache this promise, because user may have changed the permission anytime
this.messaging.requestPermission()
.then(function() {
onLog('Notification permission granted.');
self.getSubscription()
.then(function(currentToken) {
if (currentToken) {
deferred.resolve(currentToken);
onLog('Notification token retrieved.');
onToken(currentToken);
} else {
// Show permission UI.
//updateUIForPushPermissionRequired();
deferred.reject(noTokenError);
onUI({action: 'showPermissionUI'});
}
})
.catch(function(err) {
deferred.reject(noTokenError);
onLog('An error occurred while retrieving token. ', err);
});
})
.catch(function(err) {
deferred.reject(noPermissionError);
onLog('An error occurred while retrieving token. ', err);
});
this.setUpHandlers(onToken, onMessage);
return deferred.promise;
};
this.unsubscribe = function() {
this.unsubscribeTokenRefresh();
this.unsubscribeMessages();
delete this.registerWorkerPromise;
delete this.tokenPermissionPromise;
var deferred = $q.defer();
deferred.resolve();
return deferred.promise;
};
this.getRegistration = function () {
if (this.registerWorkerPromise) return this.registerWorkerPromise;
var self = this;
var deferred = $q.defer();
if ('serviceWorker' in navigator) {
console.log('Service Worker is supported');
navigator.serviceWorker.register('firebase-messaging-sw.js')
.then(function (reg) {
self.messaging.useServiceWorker(reg);
deferred.resolve();
console.log('Registration successful', reg);
}).catch(function (e) {
deferred.reject(e);
console.error('Registration unsuccessful', e);
});
} else {
deferred.resolve();
}
this.registerWorkerPromise = deferred.promise;
return this.registerWorkerPromise;
}
this.getSubscription = function () {
if (this.tokenPermissionPromise) return this.tokenPermissionPromise;
this.tokenPermissionPromise = this.messaging.getToken();
return this.tokenPermissionPromise;
};
}
]);
//
// * ********* * Service worker code: firebase-messaging-sw.js * ********* *
//
'use strict';
console.log('Starting service worker');
if( 'function' === typeof importScripts) {
importScripts('https://www.gstatic.com/firebasejs/3.5.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.5.0/firebase-messaging.js');
importScripts('core/decoder.js');
// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
'messagingSenderId': '502712538968'
});
// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();
var decoder = new Decoder();
messaging.setBackgroundMessageHandler(function(payload) {
var data = payload || {};
var shinyData = decoder.run(data);
console.log('[firebase-messaging-sw.js] Received background message ', payload, shinyData);
return self.registration.showNotification(shinyData.title, {
body: shinyData.body,
icon: shinyData.icon,
data: {url: shinyData.tag}
})
});
/*
self.addEventListener('push', function(event) {
console.log('Received a push message', event);
var data = {};
if (event.data) {
// Chrome does not seem to support it for now
data = event.data.json();
console.log('Data received in push message', data);
// if (port) port.postMessage(data);
}
var shinyData = decoder.run(data);
show(event, shinyData);
});
*/
self.addEventListener('notificationclick', function(event) {
console.log('On notification click: ', event.notification.data.url);
// Android doesn’t close the notification when you click on it
// See: http://crbug.com/463146
event.notification.close();
// This looks to see if the current is already open and
// focuses if it is
console.log('Notification click: data.url ', event.notification.data.url);
event.notification.close();
var url = /localhost:3999|dev-piquemeup.firebaseapp.com/;
var newurl = "/chat";
if (event.notification.data.url) {
newurl = event.notification.data.url;
}
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
event.waitUntil(
clients.matchAll({
type: 'window'
})
.then(function(windowClients) {
for (var i = 0; i < windowClients.length; i++) {
var client = windowClients[i];
if (url.test(client.url) && 'focus' in client) {
if (endsWith(client.url, "/app.html#" + newurl)) {
console.log("******** Yes it matched *******");
return client.focus();
}
return client.navigate("/app.html#" + newurl)
.then(client => client.focus());
}
}
if (clients.openWindow) {
return clients.openWindow("/app.html#" + newurl);
}
})
);
});
}
@dileeppipra
Copy link

after line number 210 after focus i want to navigate to url
please suggest me

@arissa34
Copy link

arissa34 commented Aug 9, 2021

Did you find a solution ?

@dileeppipra
Copy link

dileeppipra commented Aug 19, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment