Skip to content

Instantly share code, notes, and snippets.

@senthilp
Last active Aug 15, 2018
Embed
What would you like to do?
eBay Push Subscription
/* global firebase */
'use strict';
const chauffeurElem = document.querySelector('.chauffeur-script');
function lazyLoad(url) {
return new Promise((resolve, reject) => {
const scriptElem = document.createElement('script');
scriptElem.type = 'application/javascript';
scriptElem.async = true;
scriptElem.onload = resolve;
scriptElem.onerror = reject;
scriptElem.src = url;
const firstScript = document.getElementsByTagName('script')[0];
firstScript.parentNode.insertBefore(scriptElem, firstScript);
});
}
function emitEvent(eventName, id) {
const eventArg = id && { id };
const event = new CustomEvent(eventName, { detail: eventArg });
document.dispatchEvent(event);
}
function getServerEndpoint() {
const serverEndpoint = chauffeurElem.dataset.serverEndpoint;
if (!serverEndpoint) {
throw Error('Server endpoint not available');
}
return serverEndpoint;
}
function getFirebaseConfig() {
const { apiKey, senderId } = chauffeurElem.dataset;
return {
apiKey,
messagingSenderId: senderId
};
}
async function loadAndInitFirebase() {
try {
await lazyLoad(chauffeurElem.dataset.sdk);
firebase.initializeApp(getFirebaseConfig());
} catch (ex) {
emitEvent('subscribe-error', 'ERR_FIREBASE_LOAD');
throw Error(ex);
}
}
async function getServiceWorkerRegistration() {
try {
return await navigator.serviceWorker.getRegistration('/p');
} catch (ex) {
emitEvent('subscribe-error', 'ERR_SW_REG');
throw Error(ex);
}
}
async function requestPermission(messaging) {
try {
await messaging.requestPermission();
} catch (ex) {
if (ex && ex.code === 'messaging/permission-default') {
emitEvent('subscribe-denied', 'ERR_DEFAULT');
} else {
emitEvent('subscribe-denied', 'ERR_PERMISSION');
}
throw Error(ex);
}
}
async function getToken(messaging) {
try {
return await messaging.getToken();
} catch (ex) {
emitEvent('subscribe-error', 'ERR_TOKEN_FETCH');
throw Error(ex);
}
}
async function sendTokenToServer(token) {
try {
const serverEndpoint = getServerEndpoint();
const response = await fetch(serverEndpoint, {
body: JSON.stringify({ token }),
credentials: 'include',
headers: {
'content-type': 'application/json'
},
method: 'POST',
mode: 'cors'
});
if (response.status.toString().indexOf('2') !== 0) {
throw new Error('Server response status not 200');
}
} catch (ex) {
emitEvent('subscribe-error', 'ERR_MDNS_TOKEN');
throw Error(ex);
}
}
function monitorTokenRefresh(messaging) {
messaging.onTokenRefresh(async() => {
try {
const token = await getToken(messaging);
await sendTokenToServer(token);
emitEvent('subscribe-token-refresh');
} catch (ex) {
// All errors have be handled by indiviudal functions
}
});
}
async function subscribe(syncToken = false) {
try {
// Load and init firebase SDK
if (typeof firebase === 'undefined') {
await loadAndInitFirebase('firebase');
}
const messaging = firebase.messaging();
// Use registered SW
const swReg = await getServiceWorkerRegistration();
messaging.useServiceWorker(swReg);
// Request user perimission
// If called only for syncing token, the user has already granted persmission
if (!syncToken) {
await requestPermission(messaging);
}
const token = await getToken(messaging);
await sendTokenToServer(token);
monitorTokenRefresh(messaging);
emitEvent('subscribe-success');
} catch (ex) {
// All errors have be handled by indiviudal functions
}
}
function init() {
if (!chauffeurElem) {
return;
}
Object.defineProperty(chauffeurElem, 'subscribe', {
value: subscribe
});
}
init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment