1. 程式人生 > >Progressive Web Apps(PWA)核心技術-使用Firebase Cloud Messaging實現推送通知

Progressive Web Apps(PWA)核心技術-使用Firebase Cloud Messaging實現推送通知

Chrome目前使用Firebase雲訊息傳遞(FCM)作為其推送服務。 FCM最近採用了Web Push協議。 FCM是Google雲訊息傳遞(GCM)的後續產品,支援相同的功能和更多功能。

要使用Firebase雲訊息傳遞,您需要在Firebase上設定專案(請參閱VAPID部分以繞過此步驟)。 大致流程如下:

1、在Firebase控制檯中,選擇建立新專案。
2、提供專案名稱,然後單擊建立專案。
3、單擊導航面板中專案名稱旁邊的“設定”圖示,然後選擇“專案設定”。
4、開啟雲訊息傳遞選項卡。 您可以在此頁面找到您的伺服器金鑰和發件人ID。 儲存這些值。
為了將FCM郵件路由到正確的service worker,需要知道發件人ID。 通過將gcm_sender_id屬性新增到應用程式的manifest.json檔案來提供此功能。 例如:

{
  "name": "Push Notifications app",
  "gcm_sender_id": "370072803732"
}

要讓FCM將沒有負載的通知推送到您的Web客戶端,請求必須包含以下內容:

  • 訂閱端點URL
  • 公共伺服器金鑰。 FCM使用它來檢查發出請求的伺服器是否允許向接收使用者傳送訊息。
    生產站點或應用程式通常會設定一個服務,以讓伺服器與FCM進行互動。

我們可以使用cURL在我們的應用程式中測試推送訊息。 我們可以向推送服務傳送一個名為“tickle”的空訊息,然後推送服務向瀏覽器傳送訊息。 如果通知顯示,那麼我們已經做了一切正確的,我們的應用程式已準備好從伺服器推送訊息。

傳送請求到FCM發出推送訊息的cURL命令:

curl "ENDPOINT_URL" --request POST --header "TTL: 60" --header "Content-Length: 0" \
--header "Authorization: key=SERVER_KEY"

例如:

curl "https://android.googleapis.com/gcm/send/fYFVeJQJ2CY:APA91bGrFGRmy-sY6NaF8a...gls7HZcwJL4 \ 
LFxjg0y0-ksEhKjpeFC5P" --request POST --header "TTL: 60"
--header "Content-Length: 0" \ --header "Authorization: key=AIzaSyD1JcZ8WM1vTtH6Y0tXq_Pnuw4jgj_92yg"

向用戶推送訊息相對比較容易。 但是,到目前為止,我們傳送的通知都是空的。 Chrome和Firefox支援使用推送訊息將資料傳送給service worker的功能。
我們先來看看service worker需要進行哪些更改才能將資料從推送訊息中提取出來。

self.addEventListener('push', function(e) {
  var body;

  if (e.data) {
    body = e.data.text();
  } else {
    body = 'Push message no payload';
  }

  var options = {
    body: body,
    icon: 'images/notification-flat.png',
    vibrate: [100, 50, 100],
    data: {
      dateOfArrival: Date.now(),
      primaryKey: 1
    },
    actions: [
      {action: 'explore', title: 'Explore this new world',
        icon: 'images/checkmark.png'},
      {action: 'close', title: 'I don't want any of this',
        icon: 'images/xmark.png'},
    ]
  };
  e.waitUntil(
    self.registration.showNotification('Push Notification', options)
  );
});

當我們收到帶有資料的推送通知時,資料直接在事件物件上可用。 這些資料可以是任何型別,json,blob,array或text。

服務端推送
以nodejs為例:
安裝推送服務:npm install web-push

var webPush = require('web-push');

var pushSubscription = {"endpoint":"https://android.googleapis.com/gcm/send/f1LsxkKphfQ:APA91bFUx7ja4BK4JVrNgVjpg1cs9lGSGI6IMNL4mQ3Xe6mDGxvt_C_gItKYJI9CAx5i_Ss6cmDxdWZoLyhS2RJhkcv7LeE6hkiOsK6oBzbyifvKCdUYU7ADIRBiYNxIVpLIYeZ8kq_A",
"keys":{"p256dh":"BLc4xRzKlKORKWlbdgFaBrrPK3ydWAHo4M0gs0i1oEKgPpWC5cW8OCzVrOQRv-1npXRWk8udnW3oYhIO4475rds=", "auth":"5I2Bu2oKdyy9CwL8QVF0NQ=="}};

var payload = 'Here is a payload!';

var options = {
  gcmAPIKey: 'AIzaSyD1JcZ8WM1vTtH6Y0tXq_Pnuw4jgj_92yg',
  TTL: 60
};

webPush.sendNotification(
  pushSubscription,
  payload,
  options
);

本示例將訂閱物件,有效內容和伺服器金鑰傳遞給sendNotification方法。 它還傳遞一個生存時間,這是以秒為單位的值,它描述了推送服務保留推送訊息的時間(預設為四周)。

通過VAPID身份驗證識別您的服務
Web推送協議旨在通過保持使用者匿名性,並且不需要您的應用程式和推送服務之間的高度認證來尊重使用者的隱私。這提出了一些挑戰:

  • 未經認證的推送服務面臨更大的攻擊風險
  • 擁有端點的任何應用程式伺服器都能夠向用戶傳送訊息
  • 如果出現問題,推送服務無法與開發者聯絡
    解決方案是讓釋出者使用“自願應用伺服器標識”(VAPID)Web推送協議。這至少為應用程式伺服器提供了一個穩定的身份,這也可以包括聯絡資訊,例如電子郵件地址。

該規範列出了使用VAPID的幾個好處:

  • 推送服務可以使用一致的身份為應用程式伺服器建立期望行為。然後可以使用明顯偏離既定標準來觸發異常處理程式。
  • 在特殊情況下,自願提供的聯絡資訊可用於聯絡應用伺服器運營商。
  • 部署推送服務的經驗表明,軟體錯誤或異常情況會導致推送訊息量大幅增加。聯絡應用程式伺服器的運營商已被證明是有價值的。
  • 即使沒有可用的聯絡資訊,在選擇是否丟棄推送訊息時,具有良好聲譽的應用程式伺服器可能優先於未識別的應用程式伺服器。
  • 使用VAPID還可以避免傳送推送訊息的FCM特定步驟。您不再需要Firebase專案,gcm_sender_id或Authorization標頭。

使用VAPID
這個過程非常簡單:

您的應用程式伺服器建立一個公鑰/私鑰對。 公鑰是給你的web app。
當用戶選擇接收推送時,將公鑰新增到subscribe()呼叫options物件。
當您的伺服器傳送推送訊息時,請將簽名的JSON Web Token與公鑰一起包含在內。

建立一個公鑰/私鑰對
以下是規範中有關VAPID公鑰/私鑰格式的相關部分:

應用程式伺服器應該在P-256曲線上生成並維護一個可用於橢圓曲線數字簽名(ECDSA)的簽名金鑰對。
可以藉助web-push node library完成這部分:

function generateVAPIDKeys() {  
  const vapidKeys = webpush.generateVAPIDKeys();
  return {
    publicKey: vapidKeys.publicKey,  
    privateKey: vapidKeys.privateKey,  
  };  
}

訂閱公鑰
要訂閱一個Chrome使用者使用VAPID公鑰進行推送,請使用subscribe()方法的applicationServerKey引數將公鑰作為Uint8Array傳遞。

const publicKey = new Uint8Array([0x40x370x770xfe,....]);
serviceWorkerRegistration.pushManager.subscribe(
  {
     userVisibleOnly:true,
     applicationServerKey:publicKey
  }
);

您將通過檢查生成的訂閱物件中的端點來了解它是否工作正常; 如果來源是fcm.googleapis.com,則表示正在執行。

注意:儘管這是一個FCM URL,但是使用Web推送協議而不是FCM協議,這樣您的伺服器端程式碼將適用於任何推送服務。
傳送推送資訊

要使用VAPID傳送訊息,可以使用另外兩個HTTP標頭進行正常的Web推送協議請求:Authorization header和JWT header。

  • Authorization header

授權標頭是一個帶有“WebPush”的簽名JSON Web Token(JWT)。

構成格式為:
<JWTHeader>.<Payload>.<Signature>

JWT header:

{  
  "typ": "JWT",  //型別
  "alg": "ES256"  //簽名演算法名稱
}

Payload:(這個JSON物件是base64 url編碼)

{  
    "aud": "http://push-service.example.com",  //可以通過const audience = new URL(subscription.endpoint).origin獲得
    "exp": Math.floor((Date.now() / 1000) + (12 * 60 * 60)),  //過期時間
    "sub": "mailto: [email protected]"  //可以是一個聯絡的url或mailto
}

Signature
這個簽名是由編碼過後的header和payload用點連線然後與之前建立的VAPID生成的私鑰加密而來的。 簽名庫
簽名的JWT被用作授權頭,“WebPush”作為字首,如下所示:

WebPush eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJodHRwczovL2ZjbS5nb29nbGVhcGlzLmNvbSIsImV4cCI6MTQ2NjY2ODU5NCwic3ViIjoibWFpbHRvOnNpbXBsZS1wdXNoLWRlbW9AZ2F1bnRmYWNlLmNvLnVrIn0.Ec0VR8dtf5qb8Fb5Wk91br-evfho9sZT6jBRuQwxVMFyK5S8bhOjk8kuxvilLqTBmDXJM5l3uVrVOQirSsjq0A

這裡有幾點需要指出。 首先,授權標題字面上包含單詞WebPush,後面跟著一個空格,然後是JWT。 還要注意分隔JWT header,payload和signature的點。

Crypto-Key
與授權標題一樣,您必須將您的VAPID公鑰新增到加密金鑰標頭中,作為base64 url編碼的字串,其字首為p256ecdsa =。

p256ecdsa=BDd3_hVL9fZi9Ybo2UUzA284WG5FZR30_95YeZJsiApwXKpNcF1rRPF3foIiBHXRdJI2Qhumhf6_LFTeZaNndIo

當您使用加密資料傳送通知時,您已經使用Crypto-Key header,因此要新增應用程式伺服器金鑰,只需在新增上述內容之前新增逗號,如下:

dh=BGEw2wsHgLwzerjvnMTkbKrFRxdmwJ5S_k7zi7A1coR_sVjHmGrlvzYpAT1n4NPbioFlQkIrTNL8EH4V3ZZ4vJE,
p256ecdsa=BDd3_hVL9fZi9Ybo2UUzA284WG5FZR30_95YeZJsiApwXKpNcF1rRPF3foIiBHXRdJI2Qhumhf6_LFTeZaN

在版本52之前的Chrome中存在一個缺陷,在Crypto-key header中需要使用分號而不是逗號。

cURL傳送推送訊息:

curl "https://updates.push.services.mozilla.com/wpush/v1/gAAAAABXmk....dyR" --request POST --header "TTL: 60" --header "Content-Length: 0" --header "Authorization: WebPush eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJodHRwczovL2ZjbS5nb29nbGVhcGlzLmNvbSIsImV4cCI6MTQ2NjY2ODU5NCwic3ViIjoibWFpbHRvOnNpbXBsZS1wdXNoLWRlbW9AZ2F1bnRmYWNlLmNvLnVrIn0.Ec0VR8dtf5qb8Fb5Wk91br-evfho9sZT6jBRuQwxVMFyK5S8bhOjk8kuxvilLqTBmDXJM5l3uVrVOQirSsjq0A" --header "Crypto-Key: p256ecdsa=BDd3_hVL9fZi9Ybo2UUzA284WG5FZR30_95YeZJsiApwXKpNcF1rRPF3foIiBHXRdJI2Qhumhf6_LFTeZaNndIo"

nodejs傳送推送訊息:

var webPush = require('web-push');

var pushSubscription = {"endpoint":"https://fcm.googleapis.com/fcm/send/c0NI73v1E0Y:APA91bEN7z2weTCpJmcS-MFyfbgjtmlAWuV5YaaNw625_Rq2-f0ZrVLdRPXKGm7B3uwfygicoCeEoWQxCKIxlL3RWG2xkHs6C8-H_cxq-4Z-isAiZ3ixo84-2HeXB9eUvkfNO_t1jd5s","keys":{"p256dh":"BHxSHtYS0q3i0Tb3Ni6chC132ZDPd5uI4r-exy1KsevRqHJvOM5hNX-M83zgYjp-1kdirHv0Elhjw6Hivw1Be5M=","auth":"4a3vf9MjR9CtPSHLHcsLzQ=="}};

var vapidPublicKey = 'BAdXhdGDgXJeJadxabiFhmlTyF17HrCsfyIj3XEhg1j-RmT2wXU3lHiBqPSKSotvtfejZlAaPywJ9E-7AxXQBj4
';
var vapidPrivateKey = 'VCgMIYe2BnuNA4iCfR94hA6pLPT3u3ES1n1xOTrmyLw
';

var payload = 'Here is a payload!';

var options = {
  vapidDetails: {
    subject: 'mailto:[email protected]le.com',
    publicKey: vapidPublicKey,
    privateKey: vapidPrivateKey
  },
  TTL: 60
};

webPush.sendNotification(
  pushSubscription,
  payload,
  options
);

相關推薦

Progressive Web Apps(PWA)核心技術-使用Firebase Cloud Messaging實現通知

Chrome目前使用Firebase雲訊息傳遞(FCM)作為其推送服務。 FCM最近採用了Web Push協議。 FCM是Google雲訊息傳遞(GCM)的後續產品,支援相同的功能和更多功能。 要使用Firebase雲訊息傳遞,您需要在Firebase上設定專

Progressive Web Apps(PWA) vs Native Apps

Progressive Web Apps(PWA) vs Native AppsPWA logoA few years back the difference between a web app and a native app was huge. You didn’t have API to access

Progressive Web App(PWA)介紹

Progressive Web App(PWA)背景介紹 很多人似乎都認為Web,應用永遠不會與本機競爭,移動應用程式的可靠性速度和使用者參與,很難建立一個他們的商業案例。 你知道嗎?你知道他們曾經是對的,但有兩件事情發生了變化。 首先,事實證明,大多數人在購買手機時購買了大部分應用程式,或者不久之後大

Don’t use iOS meta tags irresponsibly in your Progressive Web Apps

Don’t use iOS meta tags irresponsibly in your Progressive Web AppsIn the last months I’ve seen several apps creating what is known as a “Progressive Web Ap

更真、更強、更快的Web應用-Progressive Web Apps

1.Progressive Web Apps2016年Progressive Web Apps(文後簡稱PWA)風勁較大,本文作者詳細梳理了PWA現狀,希望能幫助讀者更深入瞭解PWA,主要內容如下:PWA定義:描述一下PWA的緣起與使命。 PWA技術:說明完成

Windows Azure NotificationHub+Firebase Cloud Message 實現訊息推動(付原始碼)

前期專案一直用的是Windows azure NotificationHub+Google Cloud Message 實現訊息推送, 但是GCM google已經不再推薦使用,慢慢就不再維護了, 現在Google 主推 FCM, 另一方面,google在android生態中的許可權要求越來越嚴格,不像以前那

Android Firebase接入(五)-- Firebase通知Cloud Message)

Firebase Cloud Message(FCM)可以幫助Android App實現訊息推送功能,並且可以在推送通知中攜帶引數,當用戶點選推送通知時,推送中攜帶的引數資訊將傳遞到主Activity的getIntent中。一、配置Android應用並下載google-ser

Android Developers Blog: Firebase Cloud Messaging

Posted by Jingyu Shi, Partner Developer Advocate, Partner DevRel This is the second in a series of blog posts in which outline strategies and guida

高併發的核心技術-冪等的實現方案

原文地址:http://blog.csdn.net/rdhj5566/article/details/50646599 一、背景  我們實際系統中有很多操作,是不管做多少次,都應該產生一樣的效果或返回一樣的結果。  例如:  1. 前端重複提交選中的資料,應該後臺只產生對應這個資料的一個反應結果。  2.

【轉載】高併發的核心技術-冪等的實現方案

原文地址:http://blog.csdn.net/rdhj5566/article/details/50646599 一、背景 我們實際系統中有很多操作,是不管做多少次,都應該產生一樣的效果或返回一樣的結果。 例如: 1. 前端重複提交選中的資料,應該後臺只產生對應這個資料的一個反應結果。 2. 我們發起

整合Firebase Cloud Messaging (FCM)到Eclipse工程

Firebase Cloud Messaging (FCM) 是一種跨平臺訊息傳遞解決方案,您可以使用它免費且可靠地傳遞訊息和通知。(舊版 Google Cloud Messaging(GCM))。新版本的FCM官方只支援Android Studio工程,Ecl

第一屆區塊鏈技術及應用峰會“區塊鏈核心技術”分論壇預告大放

技術蒼穹,迭代未休,區塊鏈技術乘破竹之勢而來,已然問鼎2018年技術圈開年“關鍵詞Top榜”。當爆炸式的知識需求,遇上業內資源捉襟見肘的困窘現狀,區塊鏈技術及應用峰會(BTA)·中國踏浪而至,一葉扁舟,以渡正在摸著石頭過河的技術愛好者們。 作為新一代顛

《Spring Cloud Config官方文件》之通知和Spring Cloud匯流排

9. 推送通知和Spring Cloud匯流排 許多原始碼儲存庫提供者(例如Github,Gitlab或Bitbucket)會通過webhook通知你儲存庫中的變化。您可以通過提供商的使用者介面將webhook配置為您感興趣的URL和一組事件。例如, Github 將通過一個包含提交列表的JS

JavaScript是如何工作的: Web通知的機制

摘要: 如何在Web端推送訊息? 這是專門探索 JavaScript 及其所構建的元件的系列文章的第9篇。 如果你錯過了前面的章節,可以在這裡找到它們: JavaScript是如何工作的:引擎,執行時和呼叫堆疊的概述! JavaScript是如何工作的:深入V8引擎&編寫優化程式碼的5

PWA(Progressive Web App)入門系列:(三)PWA關鍵技術Manifest

前言 前面說過,讓Web App能夠達到Native App外觀體驗的主要實現技術就是PWA中的manifest技術,本章會詳細說明manifest的實現,及各個引數的具體含義,還將瞭解如何定義Web App的啟動圖示、啟動樣式等。 簡介 manifest是一種簡單的json

WEB測試(2)--WEB核心技術WEB工作過程---URL

class wpa quest www. gpo 類型 pos item src web工作過程,首先談到url地址解析。如下圖:包括5個部分 1.協議類型 https 2.主機名 www.zhihu.com (通過DNS解析出主機名) 3.端口號 圖中端口號為443

Android核心技術-day04-04-Web方式類qq登陸

package com.gaozewen.qqloginweb; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.os.

PWA(Progressive Web App)入門系列:(五)Web Worker

前言 在說Service Worker前有必要說一下Web Worker,因為Service Worker本身就屬於Web Worker的延伸,大部分功能也是基於Web Worker進行的擴充套件。 背景 眾所周知,JavaScript引擎是以單執行緒排程的方式進行,我們無法

PWA(Progressive Web App)入門系列:(四)Promise

前言 這一章說一下ES6的Promise物件。為什麼要在PWA系列的文章中講Promise呢?因為PWA中的許多技術API中都是以Promise返回的方式返回的,為了對後續章節中PWA技術API更好的理解,這裡就來說一個Promise物件。 Promise出現的背景 在Jav

PWA(Progressive Web App)入門系列:(二)相關準備

前言 在上一章中,對PWA的相關概念做了基本介紹,瞭解了PWA的組成及優勢。為了能夠更快的進入PWA的世界,這一章主要對在PWA開發中,需要注意的問題,執行的環境及除錯工具做介紹說明。 瀏覽器要求 因為目前各瀏覽器對於PWA的支援度各不一樣,在這裡為了對PWA有更好的體驗及使