我正在使用Google的firebase在浏览器中进行通知,这种方式非常正常。 如果我在特定选项卡中订阅通知,然后我更改选项卡或最小化浏览器,我会看到两个通知实例,如果收到任何通知,我只会遇到问题。
我无法弄清楚这个问题。我正在使用angular 1.5和firebase web sdk。
以下是供参考的代码。
Firebase服务工作者:
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');
// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
if(!firebase.apps.length) {
firebase.initializeApp({
'messagingSenderId': 'XXXXXXXXXXXXX'
});
}
// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();
function getUniqueId(suffix) {
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : r & 0x3 | 0x8;
return v.toString(16);
});
if (typeof(suffix) == "string" || typeof(suffix) == "number") {
return uuid + ":" + suffix;
} else {
return uuid + "";
}
}
function paramterize(url) {
var data = {};
data.type = +url.match(/type\=(\d+)/)[1];
if (data.type === 0 || data.type === 1) {
data.accept_reject = true;
}
if (data.type === 3) {
data.popup = true;
}
if (/conference_id=(\b([a-f0-9]*)\b)/.test(url)) {
data.conference_id = url.match(/conference_id=(\b([a-f0-9]*)\b)/)[1];
}
if (/idp_privilege\=(\b([Y|N])\b)/.test(url) ) {
data.idp_privilege = url.match(/idp_privilege\=(\b([Y|N])\b)/)[1];
}
if (/country_dialer\=(\+\d+)/.test(url) ) {
data.country_dialer = url.match(/country_dialer\=(\+\d+)/)[1];
}
if (/group_id\=(\b([a-f0-9]*)\b)/.test(url)) {
data.group_id = url.match(/group_id\=(\b([a-f0-9]*)\b)/)[1];
}
return data
}
var setupDone = false;
var landing_url= 'https://pro.nowconfer.com';
var storage = {
setup: function() {
return new Promise(function(resolve, reject) {
var request = indexedDB.open('nowconferdb',18);
request.onsuccess = function (e) {
setupDone = true;
var db = e.target.result;
storage.db = db;
resolve();
};
request.onupgradeneeded = function (e) {
storage.db = e.target.result;
if (storage.db.objectStoreNames.contains('notifications')) {
storage.db.deleteObjectStore('notifications');
}
storage.db.createObjectStore('notifications', {
keyPath: '_id'
});
};
});
},
transaction: function (mode) {
var trans = storage.db.transaction('notifications', mode);
return trans.objectStore('notifications');
},
add: function (notification) {
return new Promise(function(resolve, reject) {
var request = storage.transaction('readwrite').put(notification);
request.onsuccess = function () {
console.log("Successfully stored in database");
resolve(notification);
};
request.onerror = function() {
console.log("Error in storing database");
reject();
};
});
}
};
// If you would like to customize notifications that are received in the
// background (Web app is closed or not in browser focus) then you should
// implement this optional method.
// [START background_handler]
messaging.setBackgroundMessageHandler(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
const notificationTitle = 'Background Message Title';
const notificationOptions = {
body: 'Background Message body.',
icon: '/firebase-logo.png'
};
return self.registration.showNotification(notificationTitle, {
body: 'Background Message body',
icon: 'nowconfer_icon_enterprise.png'
});
});
function createDB(){
if (!setupDone) {
storage.setup().then(function() {
console.log("created");
});
}
}
self.addEventListener('install', function(event) { event.waitUntil(self.skipWaiting())});
self.addEventListener('push', function(event) {
console.log("Inside push event");
if(event.data) {
console.info('SERVICE-WORKER');
var data = JSON.parse(event.data.text());
console.log("data is :"+data);
data = data.notification;
if(data.title && (data.title == "Refresh Contacts" || data.title == "You have a group message")) return;
console.log("notification data is :"+data);
var notif_title = "Missed notification";
var notif_body = "This website has been updated.";
//var notif_icon = "https://www.pushchamp.com/static/images/notif_icon.png";
var notif_icon = "https://pro.nowconfer.com/images/Nowconfer_Logo.png";
var promises = [];
landing_url = data.click_action || landing_url;
console.log('landing_url :'+landing_url);
data._id = data.click_action.match(/_id=(\b([a-f0-9]*)\b)/)[1];
data.time = Date.now();
if(data.title.indexOf("You have a new message")==-1){
promises.push(self.registration.showNotification(data.title || notif_title, {
body: data.body || notif_body,
icon: data.icon || notif_icon,
click_action: landing_url
}));
}
Object.assign(data, paramterize(landing_url));
self.clients.matchAll().then(function(clients) {
Array.prototype.slice.call(clients).map(function(client) {
return client.postMessage(data);
});
});
if (!setupDone) {
storage.setup().then(function() {
storage.add(data);
});
}
else {
storage.add(data);
}
landing_url = data.landing_url || landing_url;
return Promise.all(promises);
}
});
self.addEventListener('install', function(event) { event.waitUntil(self.skipWaiting())});
self.addEventListener('activate', function(event) { event.waitUntil(self.clients.claim())});
self.onactivate = function(evt) {
var result;
self.clients.claim().then(function(_result) {
result = _result;
return self.clients.matchAll();
});
};
self.addEventListener('notificationclick', function(event) {
console.log('Inside notificationclick landing_url:'+landing_url);
event.notification.close();
event.waitUntil(
clients.matchAll({
type: "window"
}).then(function(clientList) {
if (landing_url!=''){
return clients.openWindow(landing_url);
}
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url == '/' && 'focus' in client)
return client.focus();
}
if (clients.openWindow) {
return clients.openWindow(landing_url);
}
})
);
});
Angular中的通知控制器: 提供关于通知被推送的事件的块
$scope.$on('push:notification', function(event, notifObj) {
var notif = {};
//console.log('notification received:'+JSON.stringify(notif["firebase-messaging-msg-data"].notification));
if(notifObj && notifObj["firebase-messaging-msg-data"] && notifObj["firebase-messaging-msg-data"].notification) {
notif = notifObj["firebase-messaging-msg-data"].notification;
notif.type = notifObj.type?notifObj.type:notif.click_action.match(/type\=(\d+)/)[1];
notif._id = notifObj._id;
notif.conference_id = notifObj.conference_id;
}else{
notif = notifObj;
}
switch (notif.type) {
case 0:
console.log("schedule Notify:"+JSON.stringify(notif));
save(notif);
break;
case 1:
save(notif);
break;
case 2:
save(notif);
break;
case 3:
save(notif);
break;
/*case 4:
me.fetchProfile().then(function() {
$rootScope.$broadcast('refresh:profile');
});
me.getContacts('refresh').then(function() {
$rootScope.$broadcast('refresh:contacts');
});
break;*/
case 5: // leave grp by others
save(notif);
me.getGroups('refresh').then(function() {
$rootScope.$broadcast('groups-refreshed');
});
break;
case 6:
//disable group chat for group_id
save(notif);
me.getGroups('refresh').then(function() {
$rootScope.$broadcast('groups-refreshed');
});
break;
case 7:
//enable only chat
me.removeConfPrivilege();
$rootScope.$broadcast('remove:conf:privilege');
console.log('case 7 is called');
break;
case 11:
save(notif);
break;
case 12:
save(notif);
console.log('Number verified notif:'+JSON.stringify(notif["firebase-messaging-msg-data"].notification));
var my_profile = me.getMe();
my_profile.mobile_number = notif.newMobileNo;
my_profile.num_verified = true;
me.setMe(my_profile).then(function(){
// console.log("set verified no to true for profile:"+JSON.stringify(my_profile));
if($state.current.title == 'profile') {
console.log("Reloading as currently in profile");
$state.go('root.profile', {}, { reload: true });
}
});
break;
case 13:
save(notif);
console.log('Number unverified notif:'+JSON.stringify(notif["firebase-messaging-msg-data"].notification));
if(notif.message){
ModalService.showModal({
templateUrl: absoluteURL('app/layout/alert.html'),
controller: 'AlertController',
inputs: {
text: notif.message
}
});
}
var my_profile = me.getMe();
console.log("got my profile:"+JSON.stringify(my_profile));
my_profile.mobile_number = notif.conference_id;
my_profile.num_verified = false;
me.setMe(my_profile).then(function(){
console.log("set verified no to false for profile:"+JSON.stringify(my_profile));
if($state.current.title == "dashboard"){
$rootScope.$broadcast('reload:dashboard');
}
});
break;
case 14:
save(notif);
// console.log('suggestion notif:'+JSON.stringify(notif));
break;
case 17:
save(notif);
// console.log('suggestion notif:'+JSON.stringify(notif));
break;
case 404:
console.log('404:'+JSON.stringify(notif));
sessionservice.destroy();
$window.location.reload();
break;
case 'offer':
save(notif);
break;
case 'missedVideoCall':
save(notif);
break;
case 'missedVideoConf':
save(notif);
break;
default:
break;
}
});
我不想要完整的解决方案,但是如果有人能够让我知道可能发生的事情,那么我可以尝试修复自己。提前致谢
答案 0 :(得分:0)
您是否登录了同一个ID?
我认为您的页面会收到同一时间前景(有窗口)和背景(无焦点窗口)。
如果我是你,当页面在前台接收消息时,我会显示小的吐司消息。
而且,这会对你有所帮助。 https://firebase.google.com/docs/cloud-messaging/js
答案 1 :(得分:0)
真正的问题是您将得到x号。通知如果x号。标签页已打开。
您可以尝试此document.hidden
document.hidden将为true。因此,在这种情况下,通知只会出现在活动标签上,而其余标签可以忽略。 您可以执行以下操作:
if (document.hidden) {
return false;
}