Cum să convertiți aplicația web ca PWA cu notificare push

În acest articol, vedem cum să convertiți o aplicație web sau un site web într-o PWA cu o notificare push folosind Firebase Cloud Messaging.

În lumea modernă, majoritatea aplicațiilor web sunt convertite într-o PWA (Progressive Web App) deoarece oferă funcții precum suport offline, notificare push, sincronizare în fundal. Caracteristicile PWA fac ca aplicația noastră web să fie mai mult ca o aplicație nativă și oferă o experiență bogată pentru utilizator.

De exemplu, companii grozave precum Twitter și Amazon și-au convertit aplicația web în PWA pentru mai multă implicare a utilizatorilor.

Ce este un PWA?

PWA = (Aplicație web) + (unele caracteristici ale aplicației native)

PWA este aceeași aplicație web (HTML+CSS+JS). Funcționează la fel ca aplicația dvs. web pe toate browserele ca și anterior. Dar poate avea caracteristici native atunci când site-ul dvs. se încarcă într-un browser modern. Face aplicația dvs. web mai puternică decât înainte și, de asemenea, o face mai scalabilă, deoarece putem prelua și stoca în cache activele din frontend, reduce solicitările către serverul dvs. backend.

Cum diferă PWA de aplicația web

  • Instalabil: aplicația dvs. web poate fi instalată ca o aplicație nativă
  • Progresiv: funcționează la fel ca aplicația dvs. web, dar cu unele funcții native
  • Experiența aplicației native: utilizatorul poate folosi și naviga în aplicația web ca un nativ, odată instalat.
  • Acces ușor: spre deosebire de aplicația noastră web, nu este nevoie ca utilizatorii noștri să introducă adrese web de fiecare dată când vizitează. Odată instalat, acesta poate fi deschis cu o singură atingere.
  • Memorarea în cache a aplicației: înainte de PWA, singurul mecanism de stocare în cache cu care aplicația noastră web este implementată este utilizarea cache-ului HTTP, care este disponibil numai pentru browser. Dar cu PWA putem stoca lucrurile în cache utilizând în sine codul clientului, care nu este disponibil într-o aplicație web.
  • Publicare în magazin (App/Play): PWA poate fi publicat în Google Play Store și IOS App Store.

Convertirea aplicației dvs. în PWA o va face doar mai puternică.

De ce afacerile ar trebui să ia în considerare PWA

În timp ce cei mai mulți dintre clienții noștri ne contactează și cer să dezvolte mai întâi soluția Web App și apoi cer aplicații Android și iOS. Tot ceea ce vom face este să construim aceeași funcționalitate în aplicația web pe aplicația Android/IOS de către o echipă separată, care necesită mai mult cost de dezvoltare și mai mult timp pentru comercializare.

Dar unii clienți au un buget limitat sau unii clienți ar putea crede că timpul de lansare pe piață este mai important pentru produsul lor.

Cele mai multe dintre cerințele clienților pot fi satisfăcute chiar de caracteristicile PWA. Pentru ei, le sugerăm numai PWA și le dăm o idee pentru a-și converti PWA în aplicație Android folosind TWA dacă doresc să se implementeze în Playstore.

Dacă cerințele dvs. au nevoie cu adevărat de funcții de aplicație native care nu pot fi satisfăcute de PWA. Clienții pot merge și dezvolta ambele aplicații după cum doresc. Dar chiar și în acel scenariu. Ei pot implementa PWA în magazinul de jocuri până la finalizarea dezvoltării Android.

Exemplu: Titan Eyeplus

Inițial, au dezvoltat o aplicație PWA și au implementat-o ​​în magazinul de jocuri folosind TWA (Trusted Web Activity). Odată ce și-au finalizat dezvoltarea aplicației Android. Au implementat aplicația lor reală pentru Android în magazinul de jocuri. Au atins atât time-to-market folosind PWA, cât și costul dezvoltării.

Caracteristici PWA

PWA oferă aplicațiilor noastre web funcții native asemănătoare aplicațiilor.

Principalele caracteristici sunt:

  • Instalabil: o aplicație web instalată ca o aplicație nativă.
  • Memorarea în cache: este posibilă stocarea în cache a aplicației, ceea ce oferă aplicației noastre suport offline.
  • Notificare Push: Notificarea Push poate fi trimisă de pe serverul nostru pentru a implica utilizatorii noștri pe site-ul nostru.
  • Geofencing: aplicația poate fi notificată printr-un eveniment ori de câte ori se schimbă locația dispozitivului.
  • Solicitare de plată: activați plata în aplicația dvs. cu o experiență excelentă pentru utilizator, cum ar fi o aplicație nativă.
  Cum să utilizați funcția Google Sheets IF

Și multe alte funcții care vor veni în viitor.

Alte caracteristici sunt:

  • Comenzi rapide: adrese URL accesibile rapid adăugate în fișierul manifest.
  • Web Share API: permiteți aplicației dvs. să primească date partajate de la alte aplicații.
  • API Badge: pentru a afișa numărul de notificări în PWA instalat.
  • API Periodic Background Sync: salvează datele utilizatorului până când acesta este conectat la rețea.
  • Selector de contacte: Folosit pentru a alege contacte de pe mobilul utilizatorului.
  • Selector de fișiere: Folosit pentru a accesa fișierul pe sistemul local/mobilul

Avantajul PWA față de aplicația nativă

Aplicația nativă funcționează mai bine decât PWA și are mai multe funcții decât PWA. Dar totuși, are câteva avantaje față de aplicația nativă.

  • PWA rulează pe mai multe platforme, cum ar fi Android, IOS, Desktop.
  • Reduce costurile de dezvoltare.
  • Implementare simplă a caracteristicilor în comparație cu o aplicație nativă.
  • Descoperibil cu ușurință deoarece PWA (site-ul web) este prietenos cu SEO
  • Securizat deoarece funcționează numai pe HTTPS

Dezavantajele PWA față de aplicația nativă

  • Sunt disponibile funcționalități limitate în comparație cu o aplicație nativă.
  • Funcțiile PWA nu sunt garantate să accepte toate dispozitivele.
  • Branding-ul PWA este scăzut, deoarece nu este disponibil în magazinul de aplicații sau în magazinul de jocuri.

Puteți implementa PWA ca aplicație Android în magazinul de jocuri folosind Android Activitate web de încredere (TWA). Îți va ajuta brandingul.

Lucruri necesare pentru a converti aplicația web în PWA

Pentru conversie, orice aplicație web sau site web în PWA.

  • Service-Worker: nucleul oricărei aplicații PWA pentru Caching, Pushes Notification, un proxy pentru solicitările noastre.
  • Fișier manifest: conține detalii despre aplicația dvs. web. Obișnuia să descărcați aplicația noastră ca o aplicație nativă pe ecranul de start.
  • Sigla aplicației: imagine de înaltă calitate 512 x 512 px pentru pictograma aplicației dvs. Logo-ul aplicației este necesar pentru PWA pe ecranul de pornire, ecranul de splash etc. Așa că trebuie să creăm un set de imagini cu un raport de 1:1 pentru APP folosind orice instrument.
  • Design receptiv: aplicația web ar trebui să fie receptivă pentru a funcționa pe diferite dimensiuni de ecran.

Ce este lucrătorul de servicii:

Un lucrător al serviciului (script la nivelul clientului) este un proxy între aplicația dvs. web și partea exterioară, furnizând notificări push pentru aplicația noastră web și acceptând stocarea în cache.

Service Worker rulează independent de javascript-ul principal. Deci nu are acces la DOM API. Se poate accesa doar API-ul IndexedDB, Preluați API-ul, Cache Storage API. Dar poate comunica cu firul principal printr-un mesaj.

Servicii prestate de lucrătorul de service:

  • Interceptarea solicitărilor HTTP din domeniul dvs. de origine.
  • Primiți notificare push de la serverul dvs.
  • Disponibilitatea offline a aplicației noastre

Lucrătorul de service vă controlează aplicația și vă poate manipula solicitările, dar rulează independent. Deci, din acest motiv, domeniul de origine trebuie să fie activat cu HTTPS pentru a evita un atac man-in-the-middle.

Ce este fișierul Manifest

Un fișier manifest (manifest.json) conține detalii despre aplicația noastră PWA pentru a spune browserului.

  • nume: numele aplicației
  • short_name: Nume scurt pentru aplicația noastră. Dacă este prevăzut
  • cu atât numele proprietății, cât și nume_scurt, browserul va lua nume_scurt.
  • description: Descriere pentru a descrie aplicația noastră.
  • start_url: Pentru a specifica pagina de pornire a aplicației când a fost lansat PWA.
  • pictograme: set de imagini pentru PWA pentru ecranul de pornire etc.
  • background_color: Pentru a seta culoarea de fundal a ecranului de splash în aplicația noastră PWA.
  • afișare: pentru a personaliza interfața de utilizare a browserului pentru a se afișa în aplicația noastră PWA.
  • theme_color: culoarea temei aplicației PWA.
  • domeniul de aplicare: domeniul URL al aplicației noastre de luat în considerare pentru PWA. În mod implicit, locația fișierului manifest localizat.
  • comenzi rapide: linkuri rapide pentru aplicația noastră PWA.

Convertiți aplicația web în PWA

În scopul demonstrației, am creat o structură de foldere a site-ului web tipstrick.ro cu fișiere statice.

  • index.html – pagina de start
  • articole/
    • index.html – pagina de articole
  • autori/
    • index.html – pagina autorilor
  • instrumente/
    • index.html – pagina de instrumente
  • oferte/
    • index.html – pagina de oferte
  Cum să descărcați e-mailurile Microsoft Outlook

Dacă aveți deja vreun site web sau aplicație web, încercați să îl convertiți în PWA urmând pașii de mai jos.

Creați imaginile necesare pentru PWA

În primul rând, luați sigla aplicației și decupați-o într-o dimensiune de 1:1 în 5 dimensiuni diferite. am folosit https://tools.crawlink.com/tools/pwa-icon-generator/ pentru a obține rapid diferite dimensiuni de imagine. Așa că o poți folosi și tu.

Creați un fișier manifest

În al doilea rând, creați un fișier manifest.json pentru aplicația dvs. web cu detaliile aplicației. Pentru demonstrație, am creat un fișier manifest pentru site-ul web tipstrick.ro.

{
	"name": "tipstrick.ro",
	"short_name": "tipstrick.ro",
	"description": "tipstrick.ro produces high-quality technology & finance articles, makes tools, and APIs to help businesses and people grow.",
	"start_url": "/",
	"icons": [{
		"src": "assets/icon/icon-128x128.png",
		"sizes": "128x128",
		"type": "image/png"
	}, {
		"src": "assets/icon/icon-152x152.png",
		"sizes": "152x152",
		"type": "image/png"
	}, {
		"src": "assets/icon/icon-192x192.png",
		"sizes": "192x192",
		"type": "image/png"
	}, {
		"src": "assets/icon/icon-384x384.png",
		"sizes": "384x384",
		"type": "image/png"
	}, {
		"src": "assets/icon/icon-512x512.png",
		"sizes": "512x512",
		"type": "image/png"
	}],
	"background_color": "#EDF2F4",
	"display": "standalone",
	"theme_color": "#B20422",
	"scope": "/",
	"shortcuts": [{
			"name": "Articles",
			"short_name": "Articles",
			"description": "1595 articles on Security, Sysadmin, Digital Marketing, Cloud Computing, Development, and many other topics.",
			"url": "https://geekflare.com/articles",
			"icons": [{
				"src": "/assets/icon/icon-152x152.png",
				"sizes": "152x152"
			}]
		},
		{
			"name": "Authors",
			"short_name": "Authors",
			"description": "tipstrick.ro - Authors",
			"url": "/authors",
			"icons": [{
				"src": "/assets/icon/icon-152x152.png",
				"sizes": "152x152"
			}]
		},
		{
			"name": "Tools",
			"short_name": "Tools",
			"description": "tipstrick.ro - Tools",
			"url": "https://tipstrick.ro.com/tools",
			"icons": [{
				"src": "/assets/icon/icon-152x152.png",
				"sizes": "152x152"
			}]
		},
		{
			"name": "Deals",
			"short_name": "Deals",
			"description": "tipstrick.ro - Deals",
			"url": "/deals",
			"icons": [{
				"src": "/assets/icon/icon-152x152.png",
				"sizes": "152x152"
			}]
		}
	]
}

Înregistrare Service-lucrător

creați un fișier script register-service-worker.js și service-worker.js în folderul rădăcină.

Primul, register-service-worker.js este fișierul javascript care va rula pe firul principal care poate accesa API-ul DOM. Dar service-worker.js este un script service worker care rulează independent de firul principal și durata de viață este, de asemenea, scurtă. Se rulează ori de câte ori evenimentele apelează lucrătorilor de service și rulează până când termină procesul.

Verificând fișierul javascript al firului principal, puteți verifica dacă lucrătorul de servicii este înregistrat în acesta. dacă nu, puteți înregistra scriptul service worker (service-worker.js).

inserați fragmentul de mai jos în register-service-worker.js:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
        navigator.serviceWorker.register('/service-worker.js');
    });
}

Lipiți fragmentul de mai jos în service-worker.js

self.addEventListener('install', (event) => { // event when service worker install
    console.log( 'install', event);
    self.skipWaiting();
});

self.addEventListener('activate', (event) => { // event when service worker activated
    console.log('activate', event);
    return self.clients.claim();
});

self.addEventListener('fetch', function(event) { // HTTP request interceptor
    event.respondWith(fetch(event.request)); // send all http request without any cache logic
    /*event.respondWith(
        caches.match(event.request).then(function(response) {
            return response || fetch(event. request);
        })
    );*/ // cache new request. if already in cache serves with the cache.
});

Nu ne-am concentrat asupra modului de a activa memoria cache pentru suport offline. Vorbim doar despre cum să convertim aplicațiile web în PWA.

Adăugați fișierul manifest și scriptul în eticheta all head a paginii dvs. HTML.

<link rel="manifest" href="https://tipstrick.ro.com/manifest.json">
<script src="/register-service-worker.js"></script>

Actualizați pagina după ce ați adăugat. Acum vă puteți instala aplicația ca mai jos pe mobil Chrome.

Pe ecranul de pornire, aplicația este adăugată.

Dacă utilizați WordPress. Încercați să utilizați pluginul de conversie PWA existent. Pentru vueJS sau reactJS puteți urma metoda de mai sus sau puteți utiliza modulele PWA npm existente pentru a vă accelera dezvoltarea. Deoarece modulele PWA npm sunt deja activate cu suport offline cache etc.

Activați notificarea push

Notificările push web sunt trimise către browser pentru a-i face pe utilizatorii noștri să se angajeze/interacționeze mai des cu aplicația noastră. Îl putem activa utilizând

  • API de notificare: este folosit pentru a configura modul în care notificarea noastră push ar trebui să fie afișată utilizatorului.
  • Push API: Este folosit pentru a primi mesaje de notificare trimise de pe serverul nostru către browser.

Primul pas pentru a activa notificarea push în aplicația noastră este să verificați Notification API și să obțineți permisiunea utilizatorului pentru a afișa o notificare. Pentru aceasta copiați și inserați fragmentul de mai jos în register-service-worker.js.

if ('Notification' in window && Notification.permission != 'granted') {
    console.log('Ask user permission')
    Notification.requestPermission(status => {  
        console.log('Status:'+status)
        displayNotification('Notification Enabled');
    });
}


const displayNotification = notificationTitle => {
    console.log('display notification')
    if (Notification.permission == 'granted') {
        navigator.serviceWorker.getRegistration().then(reg => {
            console.log(reg)
            const options = {
                    body: 'Thanks for allowing push notification !',
                    icon:  '/assets/icons/icon-512x512.png',
                    vibrate: [100, 50, 100],
                    data: {
                      dateOfArrival: Date.now(),
                      primaryKey: 0
                    }
                  };
    
            reg.showNotification(notificationTitle, options);
        });
    }
};

Dacă totul a mers corect. Veți primi o notificare din aplicație.

„Notificare” din fereastră ne va spune că API-ul de notificare este acceptat în acel browser. Notification.permission va spune că utilizatorului i s-a permis să arate notificarea. Dacă utilizatorul a permis aplicația noastră, valoarea va fi „acordată”. dacă utilizatorul a respins valoarea va fi „blocata”.

  10 cele mai bune instrumente și aplicații de înregistrare vocală online

Activați Firebase Cloud Messaging și Creați abonament

Acum începe partea adevărată. Pentru a trimite notificări de la serverul dvs. către utilizator, avem nevoie de un punct final/abonament unic pentru fiecare utilizator. Pentru asta, vom folosi mesageria cloud firebase.

Ca prim pas, creați un cont Firebase vizitând acest link https://firebase.google.com/ și apăsați pentru a începe.

  • Creați un nou proiect cu un nume și apăsați Continuare. Îl voi crea cu numele tipstrick.ro.
  • În pasul următor, Google Analytics este activat în mod implicit. Puteți comuta că nu avem nevoie de asta acum și apăsați Continuare. Puteți să-l activați mai târziu în consola Firebase, dacă aveți nevoie.
  • Odată ce proiectul este creat, acesta va arăta ca mai jos.
  • Apoi accesați setările proiectului și faceți clic pe mesagerie în cloud și generați chei.

    Din pașii de mai sus, aveți 3 chei.

    • cheie-server de proiect
    • Certificate push web cu cheie privată
    • Certificate web push-cheie publică

    Acum inserați fragmentul de mai jos în register-service-worker.js:

    const updateSubscriptionOnYourServer = subscription => {
        console.log('Write your ajax code here to save the user subscription in your DB', subscription);
        // write your own ajax request method using fetch, jquery, axios to save the subscription in your server for later use.
    };
    
    const subscribeUser = async () => {
        const swRegistration = await navigator.serviceWorker.getRegistration();
        const applicationServerPublicKey = 'BOcTIipY07N4Y63Y-9r7NMoJHofmCzn3Pu9g-LMsgIMGH4HVr42_LW9ia0lMr68TsTLKS3UcdkE3IcC52hJDYsY'; // paste your webpush certificate public key
        const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
        swRegistration.pushManager.subscribe({
          userVisibleOnly: true,
          applicationServerKey
        })
        .then((subscription) => {
            console.log('User is subscribed newly:', subscription);
            updateSubscriptionOnServer(subscription);
        })
        .catch((err) => {
            if (Notification.permission === 'denied') {
              console.warn('Permission for notifications was denied')
            } else {
              console.error('Failed to subscribe the user: ', err)
            }
        });
    };
    const 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;
    };
    
    const checkSubscription = async () => {
        const swRegistration = await navigator.serviceWorker.getRegistration();
        swRegistration.pushManager.getSubscription()
        .then(subscription => {
            if (!!subscription) {
                console.log('User IS Already subscribed.');
                updateSubscriptionOnYourServer(subscription);
            } else {
                console.log('User is NOT subscribed. Subscribe user newly');
                subscribeUser();
            }
        });
    };
    
    checkSubscription();

    Lipiți fragmentul de mai jos în service-worker.js.

    self.addEventListener('push', (event) => {
      const json = JSON.parse(event.data.text())
      console.log('Push Data', event.data.text())
      self.registration.showNotification(json.header, json.options)
    });

    Acum totul este pregătit în front-end. Folosind abonamentul, puteți trimite notificări push utilizatorului dvs. oricând doriți, până când nu li s-a refuzat serviciile push.

    Push din backend-ul node.js

    Puteți folosi web-push modulul npm pentru a fi mai ușor.

    Exemplu de fragment pentru a trimite o notificare push de pe serverul nodeJS.

    const webPush = require('web-push');
        // pushSubscription is nothing but subscription that you sent from your front-end to save it in DB
        const pushSubscription = {"endpoint":"https://updates.push.services.mozilla.com/wpush/v2/gAAAAABh2…E0mTFsHtUqaye8UCoLBq8sHCgo2IC7UaafhjGmVCG_SCdhZ9Z88uGj-uwMcg","keys":{"auth":"qX6AMD5JWbu41cFWE3Lk8w","p256dh":"BLxHw0IMtBMzOHnXgPxxMgSYXxwzJPxpgR8KmAbMMe1-eOudcIcUTVw0QvrC5gWOhZs-yzDa4yKooqSnM3rnx7Y"}};
        //your web certificates public-key
        const vapidPublicKey = 'BOcTIipY07N4Y63Y-9r7NMoJHofmCzn3Pu9g-LMsgIMGH4HVr42_LW9ia0lMr68TsTLKS3UcdkE3IcC52hJDYsY';
        //your web certificates private-key
        const vapidPrivateKey = 'web-certificate private key';
    
        var payload = JSON.stringify({
          "options": {
            "body": "PWA push notification testing fom backend",
            "badge": "/assets/icon/icon-152x152.png",
            "icon": "/assets/icon/icon-152x152.png",
            "vibrate": [100, 50, 100],
            "data": {
              "id": "458",
            },
            "actions": [{
              "action": "view",
              "title": "View"
            }, {
              "action": "close",
              "title": "Close"
            }]
          },
          "header": "Notification from tipstrick.ro-PWA Demo"
        });
    
        var options = {
          vapidDetails: {
            subject: 'mailto:[email protected]',
            publicKey: vapidPublicKey,
            privateKey: vapidPrivateKey
          },
          TTL: 60
        };
    
        webPush.sendNotification(
          pushSubscription,
          payload,
          options
        ).then(data => {
          return res.json({status : true, message : 'Notification sent'});
        }).catch(err => {
          return res.json({status : false, message : err });
        });

    Codul de mai sus va trimite o notificare push către abonament. Evenimentul push din lucrătorul de service va fi declanșat.

    Push din backend-ul PHP

    Pentru backend PHP puteți utiliza web-push-php pachet compozitor. Verificați exemplul de cod pentru a trimite notificări push de mai jos.

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    
    require __DIR__.'/../vendor/autoload.php';
    use MinishlinkWebPushWebPush;
    use MinishlinkWebPushSubscription;
    
    // subscription stored in DB
    $subsrciptionJson = '{"endpoint":"https://updates.push.services.mozilla.com/wpush/v2/gAAAAABh2…E0mTFsHtUqaye8UCoLBq8sHCgo2IC7UaafhjGmVCG_SCdhZ9Z88uGj-uwMcg","keys":{"auth":"qX6AMD5JWbu41cFWE3Lk8w","p256dh":"BLxHw0IMtBMzOHnXgPxxMgSYXxwzJPxpgR8KmAbMMe1-eOudcIcUTVw0QvrC5gWOhZs-yzDa4yKooqSnM3rnx7Y"}}';
    $payloadData = array (
    'options' =>  array (
                    'body' => 'PWA push notification testing fom backend',
                    'badge' => '/assets/icon/icon-152x152.png',
                    'icon' => '/assets/icon/icon-152x152.png',
                    'vibrate' => 
                    array (
                      0 => 100,
                      1 => 50,
                      2 => 100,
                    ),
                    'data' => 
                    array (
                      'id' => '458',
                    ),
                    'actions' => 
                    array (
                      0 => 
                      array (
                        'action' => 'view',
                        'title' => 'View',
                      ),
                      1 => 
                      array (
                        'action' => 'close',
                        'title' => 'Close',
                      ),
                    ),
    ),
    'header' => 'Notification from tipstrick.ro-PWA Demo',
    );
    
    // auth
    $auth = [
        'GCM' => 'your project private-key', // deprecated and optional, it's here only for compatibility reasons
        'VAPID' => [
            'subject' => 'mailto:[email protected]', // can be a mailto: or your website address
            'publicKey' => 'BOcTIipY07N4Y63Y-9r7NMoJHofmCzn3Pu9g-LMsgIMGH4HVr42_LW9ia0lMr68TsTLKS3UcdkE3IcC52hJDYsY', // (recommended) uncompressed public key P-256 encoded in Base64-URL
            'privateKey' => 'your web-certificate private-key', // (recommended) in fact the secret multiplier of the private key encoded in Base64-URL
        ],
    ];
    
    $webPush = new WebPush($auth);
    
    $subsrciptionData = json_decode($subsrciptionJson,true);
    
    
    // webpush 6.0
    $webPush->sendOneNotification(
      Subscription::create($subsrciptionData),
      json_encode($payloadData) // optional (defaults null)
    );

    Concluzie

    Sper că acest lucru vă oferă o idee despre conversia aplicațiilor web în PWA. Puteți verifica codul sursă al acestui articol Aici și demo-l Aici. Am testat notificarea push trimițând-o din backend și cu ajutorul unui exemplu de cod.