我可以在firebase-messaging-sw.js中使用Service Worker缓存功能吗? [英] Can i use service worker caching function in firebase-messaging-sw.js?

查看:66
本文介绍了我可以在firebase-messaging-sw.js中使用Service Worker缓存功能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我想将我的Web应用程序资产缓存在服务工作者中,但是我已经有了Firebase消息传递软件,我可以在其中放置代码或创建新的服务工作者吗?

So I want to cache my web app assets in a service worker, but I already have firebase messaging SW, can I put my code there or create a new service worker?

推荐答案

这对我有用: -创建两个服务工作者:sw.js(用于缓存和提取处理程序)和firebase-messaging-sw.js

This is what worked for me: - create two service workers: sw.js (for caching and fetch handler) and the firebase-messaging-sw.js

  • 如前所述,sw.js将处理您的缓存.不要在sw.js中创建推送"或"notificationclick"处理程序

  • as mentioned, sw.js will handle your caching. DO NOT create a "push" or "notificationclick" handler in sw.js

在firebase-messaging-sw.js中创建"push"和"notificationclick"处理程序.我不会在firebase-messaging-sw.js中调用任何firebase实例化代码,也不会使用firebase消息传递对象或setBackgroundMessageHandler方法.我仅使用"push"和"notificationclick"处理程序.这样做的原因是,如果您在应用中实例化了Firebase消息传递sdk,它将自动查找并安装firebase-messaging-sw.js,并且通过在其中放置推送"处理程序,您变得很聪明.

create your "push" and "notificationclick" handlers in firebase-messaging-sw.js. I do NOT call any firebase instantiating code in firebase-messaging-sw.js, and I DO NOT use the firebase messaging object or the setBackgroundMessageHandler method. I only use the "push" and "notificationclick" handlers. Reason for this is that if you instantiate the firebase messaging sdk in your app, it will automatically look for and install firebase-messaging-sw.js, and by putting your "push" handler there, you're golden.

我只注册"sw.js".初始化时,firebase sdk会自动注册firebase-messaging-sw.js.

I only register "sw.js". The firebase sdk will automatically register firebase-messaging-sw.js when you initialize it.

index.html:

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:

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事件,我想即使在前台也要显示推送通知.最终,上面的解决方案是行得通的.

I was going absolutely crazy trying to figure this out, and could not for the life of me get the setBackgroundMessageHandler event to fire, and I wanted to show push notifs even in the foreground. Ultimately the solution above is what worked.

这篇关于我可以在firebase-messaging-sw.js中使用Service Worker缓存功能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆