Skip to main content

Installation

There are two cases to integrate the Push Notifications:

Case 1: You Are the Owner of a Firebase Project

  1. Provide us with your Firebase Service Account (JSON file).
  2. Get your Firebase project configuration (documentation).
  3. Create a new service worker file, it should be named firebase-messaging-sw.js and should be placed at the root level of your server.
    • This file acts as a background script that runs separately from your web page and is responsible for receiving push notifications.
  4. Add the Snippet below to your service worker file.
  5. Fill the firebase.initializeApp with your Firebase configuration.

Case 2: MeetingDoctors Manages the Firebase Project

  1. Create a new service worker file, it should be named firebase-messaging-sw.js and should be placed at the root level of your server.
    • This file acts as a background script that runs separately from your web page and is responsible for receiving push notifications.
  2. Add the Snippet below to your service worker file.
  3. Fill the firebase.initializeApp with your Firebase configuration that you received from MeetingDoctors.

Snippet

/firebase-messaging-sw.js
// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.

importScripts('https://www.gstatic.com/firebasejs/10.12.2/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/10.12.2/firebase-messaging-compat.js');

// Function to parse new format of payload notification
(function(e,i){typeof exports=="object"&&typeof module<"u"?i(exports):typeof define=="function"&&define.amd?define(["exports"],i):(e=typeof globalThis<"u"?globalThis:e||self,i(e["payload-notification"]={}))})(this,function(e){"use strict";const i=t=>{try{return JSON.parse(t)}catch{return t}};function r(t){return Object.entries(t.data).reduce((d,[c,f])=>(d[c]=i(f),d),{})}const o=t=>{try{return!("data"in t.data)}catch{return!0}},a=t=>{if(o(t)){const n=r(t);return{data:{data:JSON.stringify(n)}}}return t};self.customPayloadNotification={isPayloadNotificationNew:o,payloadNotificationMiddleware:a},e.isPayloadNotificationNew=o,e.payloadNotificationMiddleware=a,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});

////////////////////////////////////////////////////////////////////////////////////////////
// FIREBASE WEB CREDENTIALS - https://firebase.google.com/docs/web/learn-more#config-object

firebase.initializeApp({
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: "",
});

////////////////////////////////////////////////////////////////////////////////////////////

const messaging = firebase.messaging();

messaging.onBackgroundMessage(function (backgroundMessage) {
try {
if (backgroundMessage.data && backgroundMessage.data.type === "silent") {
return;
}
} catch (_) {}
const payload = self.customPayloadNotification.payloadNotificationMiddleware(backgroundMessage);
const pushMessage = payload.data;
const pushMessageData = JSON.parse(pushMessage.data);
pushMessageData.company = "MD"
const promiseChain = clients.matchAll({ type: "window", includeUncontrolled: true })
.then(windowClients => {
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
windowClient.postMessage(pushMessageData);
}
})
.then(() => {
if (!['video-consultations', 'consultations'].includes(pushMessageData.module)) {
return null;
}
var tag = null;

switch (pushMessageData.type) {
case "open_url":
return self.registration.showNotification(pushMessageData.title, {
body: pushMessageData.message,
tag: pushMessageData.type,
data: {url: pushMessageData.url}
});
case 'video_consultation:assigned':
case 'video_call:calling':
case 'video_consultation:cancelled':
tag = 'videoCall';
break;
case 'push-notifications.new_video_consultation:assigned':
return self.registration.showNotification(pushMessageData.message.title, {
body: pushMessageData.message.body,
icon:pushMessageData.professional.avatar,
tag: pushMessageData.type,
});
case 'message_created':
tag = pushMessageData.room_id;
break;
}
return self.registration.showNotification(pushMessageData.message.title, {
body: pushMessageData.message.body,
icon:pushMessageData.professional.avatar,
tag,
badge: 1,
});
});
return promiseChain;
});
//
addEventListener('notificationclick', event => {
event.notification.close();
event.waitUntil(async function () {
if (event.notification.tag === 'push-notifications.new_video_consultation:assigned') {
const tabs = await clients.matchAll({ type: 'window', includeUncontrolled: true });
const dataToSend = {data: {type: event.notification.tag}}
const destinationUrl = '/?notificationData=' + encodeURIComponent(JSON.stringify(dataToSend))
let widgetOnTab = false;
for (const tab of tabs) {
if ('focus' in tab) {
tab.postMessage(dataToSend);
widgetOnTab = true;
return tab.focus();
}
}
if (!widgetOnTab) {
await clients.openWindow('/#/chat'+ destinationUrl);
}
return;
}

const tabs = await clients.matchAll({ type: 'window', includeUncontrolled: true });
let widgetOnTab = false;
if (event.notification.tag === "open_url") {
await clients.openWindow(event.notification.data.url);
return;
}

for (const tab of tabs) {
tab.focus();
widgetOnTab = true;
break;
}

if (!widgetOnTab) {
await clients.openWindow('/#/chat');
}
}());
});