按照教程添加前端
https://developers.google.com/web/fundamentals/codelabs/push-notifications?hl=zh-cn
后端服务使用web-push
需要审核key:
https://console.firebase.google.com/project/test-22de3/settings/cloudmessaging/web:Mzg2N2Q4MzgtNmY5MS00YTAzLTkzYTItMDc2NTczZWJkYmE2?hl=zh-cn
服务端需要能正常访问google api
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > push</title > <link href ="https://unpkg.com/ant-design-vue@1.6.4/dist/antd.min.css" rel ="stylesheet" > </head > <body > <script src ="https://cdn.jsdelivr.net/npm/vue" > </script > <script src ="https://unpkg.com/ant-design-vue@1.6.4/dist/antd.min.js" > </script > <div id ="app" > <div style ="padding: 40px;" > <a-switch :checked ="checked" @change ="onChange" :loading ="loading" > </a-switch > 开启推送 <pre v-if ="subscription" style ="max-width: 800px;white-space: pre-wrap;background-color: #EEEEEE;padding: 16px;word-break: break-all;overflow: inherit;margin-top: 15px;" > {{subscription}} </div > </div > </div > <script > const applicationServerPublicKey = 'BLkKIpmYE9jtuWVRQ6Ov8ypgYTDzxfq2i8rzj0AguQrXj1Qf-htthf9_o0ThaJWvpO9MogVjas7ENFHgFzfvMpI' ; new Vue ({ el : '#app' , data ( ) { return { loading : false , checked : false , supported : false , subscription : '' , swRegistration : undefined }; }, mounted ( ) { this .support (); this .regist (); }, methods : { onChange ( ) { this .loading = true ; if (this .checked ) { } else { const applicationServerKey = this .urlB64ToUint8Array (applicationServerPublicKey); this .swRegistration .pushManager .subscribe ({ userVisibleOnly : true , applicationServerKey : applicationServerKey }) .then (subscription => { this .$message .success ('开启成功' ); this .subscription = JSON .stringify (subscription); this .loading = false ; this .checked = true ; }, err => { this .$message .error (err); this .loading = false ; }); } }, support ( ) { if ('serviceWorker' in navigator && 'PushManager' in window ) { this .supported = true ; } else { this .supported = true ; } }, regist ( ) { navigator.serviceWorker .register ('sw.js' ) .then (swReg => { console .log ('Service Worker is registered' , swReg); this .swRegistration = swReg; this .getSubscription (); }, err => { console .error ('Service Worker Error' , err); }); }, getSubscription ( ) { this .swRegistration .pushManager .getSubscription ().then (subscription => { if (subscription) { console .log (subscription); this .subscription = JSON .stringify (subscription); this .checked = true ; } }, err => { }); }, urlB64ToUint8Array (base64String ) { const padding = '=' .repeat ((4 - (base64String.length % 4 )) % 4 ); const base64 = (base64String + padding).replace (/\-/g , '+' ).replace (/_/g , '/' ); const rawData = window .atob (base64); const outputArray = new Uint8Array (rawData.length ); for (let i = 0 ; i < rawData.length ; ++i) { outputArray[i] = rawData.charCodeAt (i); } return outputArray; } } }); </script > </body > </html >
// sw.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 'use strict' ;self.addEventListener ('push' , function (event ) { console .log ('[Service Worker] Push Received.' ); console .log (`[Service Worker] Push had this data: "${event.data.text()} "` ); const title = 'Push Codelab' ; const options = { body : 'Yay it works.' , icon : 'images/icon.png' , badge : 'images/badge.png' }; event.waitUntil (self.registration .showNotification (title, options)); });
服务端 main.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 const webpush = require ('web-push' );const pushSubscription = { endpoint : 'https://fcm.googleapis.com/fcm/send/d3FnYYAEL8c:APA91bFM5XKXi50PfFaP14R4GQ4NQ89ZZfZuY2YdS_nT3HNS1oavF66AOTuFwWA3JEs00MafFynUY3TGqXs8VebpyIpCqFD8y72nIrlc3Ge_QLVwNzcRIKz412872ncgBIitTbly99fz' , keys : { p256dh : 'BEA3VFLE-Q6rp2qYrABzn6fRjiYzaSGq5gTVGFlemTuD7WVHRX9zjbivdUEjiSLldP4WnpVYVLjl-BxqSpJGr7I' , auth : '7PzGHHVMZMh7g39f3S1vNg' } }; const vapidKeys = { privateKey : '3AtAfoXtsVOs2UjNZ-_JVZYnbfzxrjO4M0r9SZ2mw00' , publicKey : 'BLkKIpmYE9jtuWVRQ6Ov8ypgYTDzxfq2i8rzj0AguQrXj1Qf-htthf9_o0ThaJWvpO9MogVjas7ENFHgFzfvMpI' }; webpush.setGCMAPIKey ('< FCM KEY >' ); webpush.setVapidDetails ('mailto:web-push-book@gauntface.com' , vapidKeys.publicKey , vapidKeys.privateKey ); webpush.sendNotification (pushSubscription, 'The text of the notification' ).then ( res => { console .log ('success' ); }, err => { console .log (err); } );