【发布时间】:2019-10-24 03:14:17
【问题描述】:
所以我想在 Service Worker 中缓存我的 Web 应用资产,但我已经有了 Firebase 消息传递软件,我可以将我的代码放在那里还是创建一个新的 Service Worker?
【问题讨论】:
标签: firebase-cloud-messaging service-worker progressive-web-apps
所以我想在 Service Worker 中缓存我的 Web 应用资产,但我已经有了 Firebase 消息传递软件,我可以将我的代码放在那里还是创建一个新的 Service Worker?
【问题讨论】:
标签: firebase-cloud-messaging service-worker progressive-web-apps
这对我有用: - 创建两个服务工作者:sw.js(用于缓存和获取处理程序)和 firebase-messaging-sw.js
如前所述,sw.js 将处理您的缓存。不要在 sw.js 中创建“push”或“notificationclick”处理程序
在 firebase-messaging-sw.js 中创建“推送”和“通知点击”处理程序。我不会在 firebase-messaging-sw.js 中调用任何 firebase 实例化代码,也不会使用 firebase 消息传递对象或 setBackgroundMessageHandler 方法。我只使用“push”和“notificationclick”处理程序。这样做的原因是,如果您在应用程序中实例化 firebase 消息 sdk,它会自动查找并安装 firebase-messaging-sw.js,然后将您的“推送”处理程序放在那里,您就完美了。
我只注册“sw.js”。 firebase sdk 会在你初始化的时候自动注册 firebase-messaging-sw.js。
index.html:
<!-- Firebase App (the core Firebase SDK) is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/7.5.0/firebase-app.js"></script>
<!-- Add Firebase products that you want to use -->
<script src="https://www.gstatic.com/firebasejs/7.5.0/firebase-messaging.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {...config props...};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
var messaging = firebase.messaging();
// Project Settings => Cloud Messaging => Web Push certificates
//REGISTER SERVICE WORKER
window.addEventListener('load', () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js').then(function(swReg) {
return navigator.serviceWorker.ready;
})
.catch(function(error) {
console.error('Service Worker Error', error);
});
}
});
sw.js:
(function(){
//IMPORTANT: DO NOT use this service worker for push!! That is handled in firebase-messaging-sw.js
var cache_v = '1.0.43';
var cache_list = [...];
self.addEventListener('install', function(e) {...});
// intercept network requests:
self.addEventListener('fetch', function(event) {...});
// delete unused caches
self.addEventListener('activate', function(e) {...});
self.addEventListener('sync', function(event) {...});
})();
firebase-messaging-sw.js:
(function(){
self.addEventListener('push', function(event) {
let title = "Push Default Title";
let options = {};
const fallback_url = "https://www.[yourdomain.com]"; //used clicking "see all"
//promise for parsing json. firebase will send over json, but other push services, incl chrome's serviceworker push test, may just send text.
const parse_payload = (payload_obj) => {
return new Promise((resolve, reject) => {
try {
if(JSON.parse(payload_obj)){ //firebase struct
let json = JSON.parse(payload_obj);
if(json.hasOwnProperty("notification")){ //resolve to this only if notification is a property. otherwise reject
resolve(json);
} else {
reject(payload_obj);
}
}
reject(payload_obj);
} catch(e){
reject(payload_obj); //other push is just a text string
}
});
};
//struct of event.data.text() is: {"data": {"url (custom options)": [custom value]}, ..., "notification": {"title": "", "body": "", "tag": "campaign_[xxx]"}}
parse_payload(event.data.text()).then((notif) => {
title = notif.notification.title; //only resolves if notif.notification exists
console.log(notif);
options = {
body: notif.notification.body,
icon: './images/push_icon.png',
badge: './images/notif_badge.png',
data: {
url: notif.data.url || fallback_url //would have to change by item
},
actions: [{
action: 'purchase',
title: 'Purchase'
}, {
action: 'see_all',
title: '...'
}]
};
event.waitUntil(self.registration.showNotification(title, options));
}, (notif) => {
options = {
body: notif,
icon: './images/push_icon.png',
badge: './images/notif_badge.png',
data: {url: fallback_url}
};
event.waitUntil(self.registration.showNotification(title, options));
});
});
self.addEventListener('notificationclick', function(event) {
const url = event.notification.data.url;
event.notification.close(); //by default, this doesn't even close the notif. need to do that.
if(!event.action){ //did not click on an action
if (clients.openWindow && url) {
event.waitUntil(clients.openWindow(url));
}
} else { //action click, as defined in push handler
switch(event.action){
case 'purchase':
if (clients.openWindow && url) {
event.waitUntil(clients.openWindow(url)); //if clicking purchase, use specific url sent over in push
}
break;
case 'see_all':
if (clients.openWindow) {
event.waitUntil(clients.openWindow(fallback_url)); //clicking see all, so send to fallback
}
break;
}
}
});
})();
想弄清楚这一点我简直要疯了,而且我一辈子都无法触发 setBackgroundMessageHandler 事件,我什至想在前台显示推送通知。最终,上述解决方案奏效了。
【讨论】: