Last active
August 15, 2018 14:40
-
-
Save senthilp/387d68fe49cd2721d7fa05ace4f04fbe to your computer and use it in GitHub Desktop.
eBay Push Subscription
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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