如何使用推送通知將 WebApp 轉換為 PWA
已發表: 2022-03-20在本文中,我們將了解如何使用 Firebase 雲消息傳遞將 Web 應用程序或網站轉換為帶有推送通知的 PWA。
在現代世界中,大多數 Web 應用程序正在轉換為 PWA(漸進式 Web 應用程序),因為它提供了離線支持、推送通知、後台同步等功能。 PWA 功能使我們的 Web 應用程序更像原生應用程序,並提供豐富的用戶體驗。
例如,像 Twitter 和亞馬遜這樣的大公司已經將他們的 Web 應用程序轉換為 PWA 以提高用戶參與度。
什麼是 PWA?
PWA = (Web App) + (一些原生應用功能)
PWA 是您的同一個 Web 應用程序(HTML+CSS+JS)。 它在所有瀏覽器上的工作方式與您的 Web 應用程序相同,就像以前一樣。 但是當您的網站在現代瀏覽器上加載時,它可以具有本機功能。 它使您的 Web 應用程序比以前更強大,也使其更具可擴展性,因為我們可以在前端預取和緩存資產,它減少了對後端服務器的請求。
PWA 與 Web App 有何不同
- 可安裝:您的 Web 應用可以像原生應用一樣安裝
- 漸進式:與您的網絡應用程序相同,但具有一些本機功能
- 原生應用體驗:一旦安裝,用戶就可以像原生應用一樣使用和導航 Web 應用。
- 易於訪問:與我們的網絡應用程序不同,我們的用戶無需在每次訪問時都輸入網址。 安裝後,只需輕輕一按即可打開。
- 應用程序緩存:在 PWA 之前,我們的 Web 應用程序實現的唯一緩存機制是使用僅對瀏覽器可用的 HTTP 緩存。 但是使用 PWA,我們可以使用 Web 應用程序中不可用的客戶端代碼本身來緩存內容。
- (App/Play) 商店發布: PWA 可以在 Google Play Store 和 IOS App Store 發布。
將您的應用程序轉換為 PWA 只會使其更強大。
為什麼企業應該考慮 PWA
雖然我們的大多數客戶聯繫我們並要求首先開發 Web App 解決方案,然後他們要求 Android 和 iOS 應用程序。 我們要做的就是由一個單獨的團隊在 web 應用程序中構建與 Android/IOS 應用程序相同的功能,這需要更多的開發成本和更多的上市時間。
但是有些客戶的預算有限,或者有些客戶可能認為上市時間對他們的產品更重要。
PWA 功能本身可以滿足大多數客戶端需求。 對於他們,我們只建議 PWA,如果他們想在 Playstore 中部署,我們建議他們使用 TWA 將他們的 PWA 轉換為 Android 應用程序。
如果您的需求確實需要 PWA 無法滿足的原生應用程序功能。 客戶可以按照自己的意願去開發這兩個應用程序。 但即使在那種情況下。 他們可以在 Play 商店中部署 PWA,直到 Android 開發完成。
示例:泰坦 Eyeplus
最初,他們開發了一個 PWA 應用程序,並使用 TWA(Trusted Web Activity)將其部署在 Play 商店中。 一旦他們完成了他們的 Android 應用程序開發。 他們在 Play 商店中部署了他們真正的 Android 應用程序。 他們使用 PWA 實現了上市時間和開發成本。
PWA 功能
PWA 為我們的 Web 應用程序提供了類似原生應用程序的功能。
主要特點是:
- 可安裝:像本機應用程序一樣安裝的 Web 應用程序。
- 緩存:應用程序緩存是可能的,這為我們的應用程序提供了離線支持。
- 推送通知:可以從我們的服務器發送推送通知,以吸引我們的用戶訪問我們的網站。
- 地理圍欄:只要設備位置發生變化,就可以通過事件通知應用程序。
- 支付請求:在您的應用程序中啟用支付功能,並像原生應用程序一樣提供出色的用戶體驗。
未來還有更多功能。
其他特點是:
- 快捷方式:清單文件中添加的可快速訪問的 URL。
- Web Share API:讓您的應用程序接收來自其他應用程序的共享數據。
- 徽章 API:在已安裝的 PWA 中顯示通知計數。
- 定期後台同步 API:保存用戶的數據,直到它連接到網絡。
- 聯繫人選擇器:用於從用戶的手機中選擇聯繫人。
- 文件選擇器:用於訪問本地系統/移動設備上的文件
PWA 相對於原生應用程序的優勢
本機應用程序比 PWA 性能更好,並且比 PWA 具有更多功能。 但是,它仍然比本機應用程序具有一些優勢。
- PWA 在 Android、IOS、桌面等跨平台上運行。
- 它降低了您的開發成本。
- 與本機應用程序相比,易於功能部署。
- 易於發現,因為 PWA(網站)對 SEO 友好
- 安全,因為它僅適用於 HTTPS
PWA 相對於原生應用程序的缺點
- 與本機應用程序相比,可用的功能有限。
- PWA 功能不保證支持所有設備。
- PWA 的品牌知名度很低,因為它在應用商店或 Play 商店中不可用。
您可以使用 android Trusted Web Activity (TWA) 在 Play 商店中將 PWA 部署為 Android 應用程序。 這將有助於您的品牌推廣。
將 Web App 轉換為 PWA 所需的東西
用於將任何 Web 應用程序或網站轉換為 PWA。
- Service-Worker:任何用於緩存、推送通知的 PWA 應用程序的核心,是我們請求的代理。
- 清單文件:它包含有關您的 Web 應用程序的詳細信息。 它曾經像在主屏幕上下載我們的應用程序一樣下載我們的應用程序。
- 應用程序徽標:應用程序圖標的高質量圖像 512 x 512 像素。 PWA 在主屏幕、啟動屏幕等上需要應用徽標。因此我們必須使用任何工具為我們的 APP 創建一組 1:1 比例的圖像。
- 響應式設計:Web 應用程序應該能夠響應不同屏幕尺寸的工作。
什麼是服務工作者:
服務工作者(客戶端腳本)是您的 Web 應用程序和外部之間的代理,為我們的 Web 應用程序提供推送通知並支持緩存。
Service Worker 獨立於主 javascript 運行。 所以它無法訪問 DOM API。 它只能訪問 IndexedDB API、Fetch API、Cache Storage API。 但它可以通過消息與主線程通信。
service worker 提供的服務:
- 攔截來自您的源域的 HTTP 請求。
- 從您的服務器接收推送通知。
- 我們的應用程序的離線可用性
Service Worker 控制您的應用程序並可以操縱您的請求,但它獨立運行。 因此,出於這個原因,必須使用 HTTPS 啟用源域以避免中間人攻擊。
什麼是清單文件
清單文件 (manifest.json) 包含有關我們的 PWA 應用程序的詳細信息,以告知瀏覽器。
- 名稱:應用程序的名稱
- short_name:我們的應用程序的簡稱。 如果提供
- 同時具有屬性名稱和短名稱,瀏覽器將採用短名稱。
- 描述:描述我們的應用程序的描述。
- start_url:指定我們的 PWA 啟動時應用程序的主頁。
- 圖標:用於主屏幕等的 PWA 圖像集。
- background_color:在我們的 PWA 應用程序中設置啟動畫面的背景顏色。
- display:自定義我們的瀏覽器 UI 以顯示在我們的 PWA 應用程序中。
- theme_color:PWA 應用的主題顏色。
- 範圍:我們為 PWA 考慮的應用程序的 URL 範圍。 默認為清單文件所在的位置。
- 快捷方式:我們的 PWA 應用程序的快速鏈接。
將 Web 應用程序轉換為 PWA
出於演示目的,我創建了一個帶有靜態文件的 Geekflare 網站文件夾結構。
- index.html – 主頁
- 文章/
- index.html – 文章頁面
- 作者/
- index.html – 作者頁面
- 工具/
- index.html – 工具頁面
- 交易/
- index.html – 交易頁面
如果您已經有任何網站或 Web 應用程序,請嘗試按照以下步驟將其轉換為 PWA。
為 PWA 創建所需的圖像
首先,獲取您的應用程序徽標,並以 1:1 的比例將其裁剪為 5 種不同的尺寸。 我已經使用 https://tools.crawlink.com/tools/pwa-icon-generator/ 快速獲得不同的圖像尺寸。 所以你也可以使用它。
創建清單文件
其次,使用您的應用程序詳細信息為您的 Web 應用程序創建一個 manifest.json 文件。 對於演示,我為 Geekflare 網站創建了一個清單文件。
{ “名稱”:“Geekflare”, "short_name": "Geekflare", "description": "Geekflare 製作高質量的技術和金融文章,製作工具和 API 來幫助企業和人們成長。", "start_url": "/", “圖標”:[{ "src": "assets/icon/icon-128x128.png", “尺寸”:“128x128”, “類型”:“圖像/png” }, { "src": "assets/icon/icon-152x152.png", “尺寸”:“152x152”, “類型”:“圖像/png” }, { "src": "assets/icon/icon-192x192.png", “尺寸”:“192x192”, “類型”:“圖像/png” }, { "src": "assets/icon/icon-384x384.png", “尺寸”:“384x384”, “類型”:“圖像/png” }, { "src": "assets/icon/icon-512x512.png", “尺寸”:“512x512”, “類型”:“圖像/png” }], "background_color": "#EDF2F4", “顯示”:“獨立”, "theme_color": "#B20422", “範圍”: ”/”, “捷徑”:[{ “名稱”:“文章”, "short_name": "文章", "description": "1595 篇關於安全、系統管理員、數字營銷、雲計算、開發和許多其他主題的文章。", “網址”:“/文章”, “圖標”:[{ "src": "/assets/icon/icon-152x152.png", “尺寸”:“152x152” }] }, { “名稱”:“作者”, "short_name": "作者", "description": "Geekflare - 作者", “網址”:“/作者”, “圖標”:[{ "src": "/assets/icon/icon-152x152.png", “尺寸”:“152x152” }] }, { “名稱”:“工具”, "short_name": "工具", "description": "Geekflare - 工具", “網址”:“/工具”, “圖標”:[{ "src": "/assets/icon/icon-152x152.png", “尺寸”:“152x152” }] }, { “名稱”:“交易”, "short_name": "交易", "description": "Geekflare - 優惠", “網址”:“/交易”, “圖標”:[{ "src": "/assets/icon/icon-152x152.png", “尺寸”:“152x152” }] } ] }
註冊服務工作者
在根文件夾中創建腳本文件 register-service-worker.js 和 service-worker.js。
第一個,register-service-worker.js 是 javascript 文件,將在可以訪問 DOM API 的主線程上運行。 但是 service-worker.js 是一個獨立於主線程運行的 service worker 腳本,它的生命週期也很短。 每當事件調用服務工作者時它就會運行並運行直到它完成該過程。
通過檢查主線程 javascript 文件,您可以檢查服務工作者是否在其中註冊。 如果沒有,您可以註冊服務工作者腳本(service-worker.js)。
將以下代碼段粘貼到 register-service-worker.js 中:
if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('/service-worker.js'); }); }
將以下代碼段粘貼到 service-worker.js
self.addEventListener('install', (event) => { // service worker 安裝時的事件 console.log('安裝',事件); self.skipWaiting(); }); self.addEventListener('activate', (event) => { // service worker 激活時的事件 console.log('激活',事件); 返回 self.clients.claim(); }); self.addEventListener('fetch', function(event) { // HTTP 請求攔截器 event.respondWith(fetch(event.request)); // 發送所有 http 請求,沒有任何緩存邏輯 /*event.respondWith( caches.match(event.request).then(function(response) { 返迴響應 || 獲取(事件。請求); }) );*/ // 緩存新請求。 如果已經在緩存中,則與緩存一起使用。 });
我們沒有專注於如何啟用緩存以支持離線支持。 我們只討論如何將 Web 應用程序轉換為 PWA。
在 HTML 頁面的 all head 標籤中添加清單文件和腳本。
<link rel="manifest" href="/manifest.json"> <script src="/register-service-worker.js"></script>
添加後刷新頁面。 現在您可以在移動 chrome 上安裝您的應用程序,如下所示。

在主屏幕上,應用程序被添加。

如果您使用的是 WordPress。 嘗試使用現有的 PWA 轉換器插件。 對於 vueJS 或 reactJS,您可以按照上述方法或使用現有的 PWA npm 模塊來加快您的開發速度。 因為 PWA npm 模塊已經啟用了離線支持緩存等。
啟用推送通知
Web 推送通知被發送到瀏覽器,以使我們的用戶更頻繁地與我們的應用程序互動/互動。 我們可以通過使用啟用它
- Notification API:用於配置我們的推送通知應該如何顯示給用戶。
- Push API:用於接收從我們的服務器發送到瀏覽器的通知消息。
在我們的應用程序中啟用推送通知的第一步是檢查通知 API 並從用戶那裡獲得顯示通知的權限。 對於該複製並將下面的代碼段粘貼到您的 register-service-worker.js 中。
if ('Notification' in window && Notification.permission != 'granted') { console.log('詢問用戶權限') Notification.requestPermission(狀態 => { console.log('狀態:'+狀態) displayNotification('通知已啟用'); }); } 常量 displayNotification = notificationTitle => { console.log('顯示通知') if (Notification.permission == 'granted') { navigator.serviceWorker.getRegistration().then(reg => { 控制台日誌(註冊) 常量選項 = { body: '感謝允許推送通知!', 圖標:'/assets/icons/icon-512x512.png', 振動:[100, 50, 100], 數據: { dateOfArrival: Date.now(), 主鍵:0 } }; reg.showNotification(通知標題,選項); }); } };
如果一切順利。 您將收到來自應用程序的通知。



窗口中的“通知”將告訴我們該瀏覽器支持通知 API。 Notification.permission將告訴用戶已被允許顯示通知。 如果用戶允許我們的應用程序,則該值將被“授予”。 如果用戶拒絕了該值,則該值將被“阻止”。
啟用 Firebase 雲消息傳遞並創建訂閱
現在真正的部分開始了。 為了從您的服務器向用戶推送通知,我們需要為每個用戶提供一個唯一的端點/訂閱。 為此,我們將使用 firebase 雲消息傳遞。
第一步,通過訪問此鏈接 https://firebase.google.com/ 創建一個 Firebase 帳戶,然後按開始。
- 使用名稱創建一個新項目,然後按繼續。 我將使用名稱 Geekflare 創建它。
- 在下一步中,默認情況下啟用 Google Analytics。 您可以切換我們現在不需要它,然後按繼續。 如果需要,您可以稍後在 Firebase 控制台中啟用它。
- 創建項目後,它將如下所示。

然後轉到項目設置並單擊雲消息傳遞並生成密鑰。

通過上述步驟,您獲得了 3 個密鑰。
- 項目服務器密鑰
- Web 推送證書私鑰
- 網絡推送證書公鑰
現在將以下代碼段粘貼到 register-service-worker.js 中:
常量 updateSubscriptionOnYourServer = 訂閱 => { console.log('在此處編寫您的 ajax 代碼以將用戶訂閱保存在您的數據庫中', subscription); // 使用 fetch、jquery、axios 編寫自己的 ajax 請求方法,將訂閱保存在服務器中以備後用。 }; const subscribeUser = async () => { const swRegistration = 等待 navigator.serviceWorker.getRegistration(); 常量 applicationServerPublicKey = 'BOcTIipY07N4Y63Y-9r7NMoJHofmCzn3Pu9g-LMsgIMGH4HVr42_LW9ia0lMr68TsTLKS3UcdkE3IcC52hJDYsY'; // 粘貼你的 webpush 證書公鑰 常量 applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey); swRegistration.pushManager.subscribe({ userVisibleOnly:真, 應用服務器密鑰 }) .then((訂閱) => { console.log('用戶新訂閱:', subscription); updateSubscriptionOnServer(訂閱); }) .catch((錯誤) => { if (Notification.permission === '拒絕') { console.warn('通知權限被拒絕') } 別的 { console.error('訂閱用戶失敗:', err) } }); }; 常量 urlB64ToUint8Array = (base64String) => { const padding = '='.repeat((4 - base64String.length % 4) % 4) const base64 = (base64String + padding) .replace(/\-/g, '+') .replace(/_/g, '/') 常量 rawData = window.atob(base64); 常量 outputArray = new Uint8Array(rawData.length); for (讓 i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } 返回輸出數組; }; const checkSubscription = async () => { const swRegistration = 等待 navigator.serviceWorker.getRegistration(); swRegistration.pushManager.getSubscription() .then(訂閱 => { 如果(!!訂閱){ console.log('用戶已訂閱'); updateSubscriptionOnYourServer(訂閱); } 別的 { console.log('用戶未訂閱。新訂閱用戶'); 訂閱用戶(); } }); }; 檢查訂閱();
將以下代碼段粘貼到 service-worker.js 中。
self.addEventListener('push', (event) => { 常量 json = JSON.parse(event.data.text()) console.log('推送數據', event.data.text()) self.registration.showNotification(json.header, json.options) });
現在全部設置在前端。 通過使用訂閱,您可以隨時向您的用戶發送推送通知,直到他們沒有被拒絕推送服務。
從 node.js 後端推送
您可以使用 web-push npm 模塊使其更容易。
從 nodeJS 服務器發送推送通知的示例片段。
常量 webPush = 要求('web-push'); // pushSubscription 只不過是您從前端發送的訂閱以將其保存在數據庫中 const pushSubscription = {"endpoint":"https://updates.push.services.mozilla.com/wpush/v2/gAAAAABh2…E0mTFsHtUqaye8UCoLBq8sHCgo2IC7UaafhjGmVCG_SCdhZ9Z88uGj-uwMcg","keys":{"auth":"qX6AMD5JWbu41cFWE3Lk8w","p2 :"BLxHw0IMtBMzOHnXgPxxMgSYXxwzJPxpgR8KmAbMMe1-eOudcIcUTVw0QvrC5gWOhZs-yzDa4yKooqSnM3rnx7Y"}}; //你的網絡證書公鑰 常量 vapidPublicKey = 'BOcTIipY07N4Y63Y-9r7NMoJHofmCzn3Pu9g-LMsgIMGH4HVr42_LW9ia0lMr68TsTLKS3UcdkE3IcC52hJDYsY'; //你的網絡證書私鑰 const vapidPrivateKey = '網絡證書私鑰'; var 有效負載 = JSON.stringify({ “選項”: { "body": "後端 PWA 推送通知測試", "徽章": "/assets/icon/icon-152x152.png", "icon": "/assets/icon/icon-152x152.png", “振動”:[100, 50, 100], “數據”: { “id”:“458”, }, “行動”:[{ “動作”:“視圖”, “標題”:“視圖” }, { “動作”:“關閉”, “標題”:“關閉” }] }, "header": "來自 Geekflare-PWA 演示的通知" }); 變量選項 = { 虛無細節:{ 主題:'mailto:[電子郵件保護]', 公鑰:vapidPublicKey, 私鑰:vapidPrivateKey }, 生存時間:60 }; webPush.sendNotification( 推送訂閱, 有效載荷, 選項 ).then(數據 => { return res.json({status : true, message : '通知發送'}); }).catch(錯誤 => { 返回 res.json({status : false, message : err }); });
上面的代碼將向訂閱發送推送通知。 service-worker 中的推送事件將被觸發。
從 PHP 後端推送
對於 PHP 後端,您可以使用 web-push-php 作曲家包。 檢查示例代碼以發送下面的推送通知。
<?php if ( !defined('BASEPATH')) exit('不允許直接腳本訪問'); 需要 __DIR__.'/../vendor/autoload.php'; 使用 Minishlink\WebPush\WebPush; 使用 Minishlink\WebPush\Subscription; // 訂閱存儲在數據庫中 $subsrciptionJson = '{"endpoint":"https://updates.push.services.mozilla.com/wpush/v2/gAAAAABh2…E0mTFsHtUqaye8UCoLBq8sHCgo2IC7UaafhjGmVCG_SCdhZ9Z88uGj-uwMcg","keys":{"auth":"qX6AMD5JWbu41cFWE3L8"p526dh8 ":"BLxHw0IMtBMzOHnXgPxxMgSYXxwzJPxpgR8KmAbMMe1-eOudcIcUTVw0QvrC5gWOhZs-yzDa4yKooqSnM3rnx7Y"}}'; $payloadData = 數組 ( '選項' => 數組 ( 'body' => '後端的 PWA 推送通知測試', '徽章' => '/assets/icon/icon-152x152.png', '圖標' => '/assets/icon/icon-152x152.png', '振動' => 大批 ( 0 => 100, 1 => 50, 2 => 100, ), '數據' => 大批 ( 'id' => '458', ), '行動' => 大批 ( 0 => 大批 ( '動作' => '視圖', '標題' => '視圖', ), 1 => 大批 ( '動作' => '關閉', '標題' => '關閉', ), ), ), 'header' => '來自 Geekflare-PWA Demo 的通知', ); // 認證 $身份驗證 = [ 'GCM' => 'your project private-key', // 已棄用且可選,此處僅出於兼容性原因 'VAPID' => [ 'subject' => 'mailto:[email protected]', // 可以是 mailto: 或您的網站地址 'publicKey' => 'BOcTIipY07N4Y63Y-9r7NMoJHofmCzn3Pu9g-LMsgIMGH4HVr42_LW9ia0lMr68TsTLKS3UcdkE3IcC52hJDYsY', //(推薦)以 Base64-URL 編碼的未壓縮公鑰 P-256 'privateKey' => 'your web-certificate private-key', //(推薦)實際上是 Base64-URL 中編碼的私鑰的秘密乘數 ], ]; $webPush = 新的 WebPush($auth); $subsrciptionData = json_decode($subsrciptionJson,true); // 網絡推送 6.0 $webPush->sendOneNotification( 訂閱::create($subsrciptionData), json_encode($payloadData) // 可選(默認為空) );
結論
我希望這能讓您對將 Web 應用程序轉換為 PWA 有所了解。 您可以在此處查看本文的源代碼並在此處進行演示。 我也在示例代碼的幫助下通過從後端發送推送通知來測試推送通知。