2017-07-18 68 views
2

我正在使用FCM處理通知,直到當我的Web應用程序位於後臺時需要從firebase-messaging-sw.js更新我的用戶界面時,它才能正常工作。當應用程序處於後臺時更新Web應用程序用戶界面FCM

  1. 我的第一個問題是:是否有可能通過一個服務人員來更新我的web應用程序的用戶界面的背景(當用戶沒有專注於Web應用程序)

  2. 其次,如果是這樣,如何?因爲我嘗試了幾件事情,但它沒有工作,顯然我做錯了什麼,當它工作時,我的Web應用程序就在前臺。我究竟做錯了什麼?

我的代碼如下。

my-firebase-service-sw.js

// [START initialize_firebase_in_sw] 
// 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/4.1.1/firebase-app.js'); 
importScripts('https://www.gstatic.com/firebasejs/4.1.1/firebase-messaging.js'); 


// My Custom Service Worker Codes 
var CACHE_NAME = 'assembly-v0.1.3.1'; 
var urlsToCache = [ 
    '/', 
    'lib/vendors/bower_components/animate.css/animate.min.css', 
    'lib/vendors/bower_components/sweetalert/dist/sweetalert.css', 
    'lib/css/app_1.min.css', 
    'lib/css/app_2.min.css', 
    'lib/css/design.css' 
]; 
var myserviceWorker; 
var servicePort; 


// Install Service Worker 
self.addEventListener('install', function (event) { 
    console.log('installing...'); 
    // Perform install steps 
    event.waitUntil(
    caches.open(CACHE_NAME) 
    .then(function (cache) { 
    console.log('Opened cache'); 
    return cache.addAll(urlsToCache); 
    }) 
    ); 
    console.log('installed...'); 
}); 

    // Service Worker Active 
    self.addEventListener('activate', function (event) { 
    console.log('activated!'); 
    // here you can run cache management 
    var cacheWhitelist = [CACHE_NAME]; 

    event.waitUntil(
    caches.keys().then(function (cacheNames) { 
     return Promise.all(
     cacheNames.map(function (cacheName) { 
      if (cacheWhitelist.indexOf(cacheName) === -1) { 
      return caches.delete(cacheName); 
      } 
     }) 
    ); 
    }) 
); 
}); 


self.addEventListener('fetch', function (event) { 
    event.respondWith(
    caches.match(event.request) 
     .then(function (response) { 
     // Cache hit - return response 
     if (response) { 
      return response; 
     } 

     // IMPORTANT: Clone the request. A request is a stream and 
     // can only be consumed once. Since we are consuming this 
     // once by cache and once by the browser for fetch, we need 
     // to clone the response. 
     var fetchRequest = event.request.clone(); 

     return fetch(fetchRequest).then(
      function (response) { 
      // Check if we received a valid response 
      if (!response || response.status !== 200 || response.type !== 'basic') { 
       return response; 
      } 

     // IMPORTANT: Clone the response. A response is a stream 
     // and because we want the browser to consume the response 
     // as well as the cache consuming the response, we need 
     // to clone it so we have two streams. 
     var responseToCache = response.clone(); 

     caches.open(CACHE_NAME) 
      .then(function (cache) { 
      cache.put(event.request, responseToCache); 
      }); 

     return response; 
     } 
    ); 
    }) 
); 
}); 

self.addEventListener('message', function (event) { 
    console.log("SW Received Message: " + event.data); 
    // servicePort = event; 
    event.ports[0].postMessage("SW Replying Test Testing 4567!"); 
}); 

myserviceWorker = self; 


// Initialize the Firebase app in the service worker by passing in the 
// messagingSenderId. 
firebase.initializeApp({ 
    'messagingSenderId': '393093818386' 
}); 

// Retrieve an instance of Firebase Messaging so that it can handle background 
// messages. 
const messaging = firebase.messaging(); 
// [END initialize_firebase_in_sw] 

// 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); 
// Customize notification here 
// send to client 
console.log('Sending data to notification'); 
try { 
     myserviceWorker.clients.matchAll().then(function (clients) { 
     clients.forEach(function (client) { 
     console.log('sending to client ' + client); 
     client.postMessage({ 
      "msg": "401", 
      "dta": payload.data 
     }); 
    }) 
    }); 
} catch (e) { 
    console.log(e); 
} 
const notificationTitle = payload.data.title;; 
const notificationOptions = { 
    body: payload.data.body, 
    icon: payload.data.icon, 
    click_action: "value" 
}; 

return self.registration.showNotification(notificationTitle, 
notificationOptions); 
}); 
// [END background_handler] 

我主要的JavaScript文件,接收的有效載荷。它在應用程序處於前臺時收到它。我的主要關注和問題是當應用程序處於後臺時接收有效載荷,前臺的所有活動都可以正常工作。

回答

0

即使您的網站打開但未聚焦,也可以更新UI。
當您獲得所有客戶列表時,只需添加啓用選項includeUncontrolled
例子:

messaging.setBackgroundMessageHandler(function (payload) { 
    console.log('[firebase-messaging-sw.js] Received background message ', payload); 
    self.clients.matchAll({includeUncontrolled: true}).then(function (clients) { 
     console.log(clients); 
     //you can see your main window client in this list. 
     clients.forEach(function(client) { 
      client.postMessage('YOUR_MESSAGE_HERE'); 
     }) 
    }) 
}); 

在您的主頁上,只需添加監聽從服務人員的消息。
例如:

navigator.serviceWorker.addEventListener('message', function (event) { 
    console.log('event listener', event); 
}); 

詳情請參閱Clients.matchAll()

相關問題