【问题标题】:Can i use service worker caching function in firebase-messaging-sw.js?我可以在 firebase-messaging-sw.js 中使用服务工作者缓存功能吗?
【发布时间】:2019-10-24 03:14:17
【问题描述】:

所以我想在 Service Worker 中缓存我的 Web 应用资产,但我已经有了 Firebase 消息传递软件,我可以将我的代码放在那里还是创建一个新的 Service Worker?

【问题讨论】:

    标签: firebase-cloud-messaging service-worker progressive-web-apps


    【解决方案1】:

    这对我有用: - 创建两个服务工作者: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 事件,我什至想在前台显示推送通知。最终,上述解决方案奏效了。

    【讨论】:

      猜你喜欢
      • 2016-05-18
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 2019-07-04
      • 1970-01-01
      • 1970-01-01
      • 2016-10-15
      • 1970-01-01
      相关资源
      最近更新 更多