Hur man konverterar WebApp som PWA med Push Notification

I den här artikeln ser vi hur man konverterar en webbapplikation eller webbplats till en PWA med ett push-meddelande med Firebase Cloud Messaging.

I den moderna världen konverteras de flesta webbapplikationer till en PWA (Progressive Web App) eftersom den ger funktioner som offlinesupport, push-meddelanden, bakgrundssynkronisering. PWA-funktioner gör vår webbapplikation mer som en inbyggd app och ger en rik användarupplevelse.

Till exempel har stora företag som Twitter och Amazon konverterat sin webbapp till PWA för mer användarengagemang.

Vad är en PWA?

PWA = (webbapp) + (vissa inbyggda appfunktioner)

PWA är din samma webbapp (HTML+CSS+JS). Den fungerar på samma sätt som din webbapp i alla webbläsare som den tidigare gjorde. Men den kan ha inbyggda funktioner när din webbplats laddas i en modern webbläsare. Det gör din webbapp mer kraftfull än tidigare och den gör den också mer skalbar eftersom vi kan förhämta och cache-tillgångar i frontend, det minskar förfrågningar till din backend-server.

Hur PWA skiljer sig från Web App

  • Installerbar: Din webbapp kan installeras som en inbyggd app
  • Progressiv: Fungerar på samma sätt som din webbapp men med några inbyggda funktioner
  • Native App Experience: Användaren kan använda och navigera i webbappen som en inbyggd, när den väl har installerats.
  • Lätttillgänglig: Till skillnad från vår webbapp, finns det inget behov för våra användare att skriva webbadresser varje gång de besöker. När den väl är installerad kan den öppnas med ett enda tryck.
  • Applikationscache: Innan PWA var den enda cachningsmekanismen som vår webbapp implementerade med att använda HTTP-cache som endast är tillgänglig för webbläsaren. Men med PWA kan vi cache saker genom att använda själva klientkoden som inte är tillgänglig i en webbapp.
  • (App/Play) butikspublicering: PWA kan publiceras i Google Play Store och IOS App Store.

Att konvertera din applikation till PWA kommer bara att göra den mer kraftfull.

Varför företag bör överväga PWA

Medan de flesta av våra kunder når oss och ber att få utveckla webbappslösningen först och sedan frågar de efter Android- och iOS-appar. Allt vi ska göra är att bygga samma funktionalitet i webbapp till Android/IOS-app av ett separat team som tar mer utvecklingskostnader och mer tid att marknadsföra.

Men vissa kunder har en begränsad budget eller så kanske en kund tycker att tid till marknaden är viktigare för deras produkt.

De flesta av kundens krav kan uppfyllas av PWA-funktionerna själva. För dem föreslår vi endast PWA och ger dem en idé om att konvertera sin PWA som en Android-app med TWA om de vill distribuera i Playstore.

Om ditt krav verkligen behöver inbyggda applikationsfunktioner som inte kan tillfredsställas av PWA. Kunder kan gå och utveckla båda applikationerna som de vill. Men även i det scenariot. De kan distribuera PWA i Play Store tills Android-utvecklingen är klar.

Exempel: Titan Eyeplus

Till en början utvecklade de en PWA-app och distribuerade den i Play Store med TWA (Trusted Web Activity). När de slutfört sin Android-applikationsutveckling. De distribuerade sin riktiga Android-applikation i Play Store. De uppnådde både time-to-market med PWA och kostnaden för utvecklingen.

PWA-funktioner

PWA ger våra webbapplikationer inbyggda appliknande funktioner.

Huvudfunktionerna är:

  • Installerbar: En webbapplikation installerad som en inbyggd app.
  • Cachning: Applikationscache är möjligt, vilket ger vår applikation offline-stöd.
  • Push Notification: Push Notification kan skickas från vår server för att engagera våra användare till vår webbplats.
  • Geofencing: Applikationen kan meddelas av en händelse när enhetens plats ändras.
  • Betalningsförfrågan: Aktivera betalning i din applikation med en fantastisk användarupplevelse som en inbyggd app.

Och många fler funktioner kommer i framtiden.

Andra funktioner är:

  • Genvägar: Snabbåtkomliga webbadresser läggs till i manifestfilen.
  • Web Share API: Låt din applikation ta emot delad data från andra applikationer.
  • Badge API: För att visa antalet aviseringar i din installerade PWA.
  • Periodic Background Sync API: sparar din användares data tills den är ansluten till nätverket.
  • Kontaktväljare: Används för att välja kontakter från användarens mobil.
  • Filväljare: Används för att komma åt filen på lokalt system/mobil

Fördelen med PWA framför Native Application

Den inbyggda appen presterar bättre än PWA och har fler funktioner än PWA. Men ändå har det vissa fördelar jämfört med den inbyggda appen.

  • PWA körs på flera plattformar som Android, IOS, Desktop.
  • Det minskar dina utvecklingskostnader.
  • Enkel funktionsdistribution jämfört med en inbyggd app.
  • Lätt att upptäcka eftersom PWA (webbplats) är SEO-vänlig
  • Säkert eftersom det bara fungerar på HTTPS

Nackdelar med PWA framför native app

  • Begränsade funktioner är tillgängliga jämfört med en inbyggd app.
  • PWA-funktioner är inte garanterade att stödja alla enheter.
  • Varumärket för PWA är lågt eftersom det inte är tillgängligt i App Store eller Play Store.

Du kan distribuera din PWA som en Android-app i Play Store med Android Trusted Web Activity (TWA). Det kommer att hjälpa ditt varumärke.

Saker som behövs för att konvertera webbapp till PWA

För konvertering, valfri webbapp eller webbplats till PWA.

  • Service-Worker: kärnan i alla PWA-appar för cachelagring, push-meddelanden, en proxy för våra förfrågningar.
  • Manifestfil: Den har detaljer om din webbapplikation. Det brukade ladda ner vår applikation som en inbyggd app på hemskärmen.
  • Applogotyp: Högkvalitativ bild 512 x 512 px för din appikon. Applogotyp behövs för PWA på hemskärmen, startskärmen etc. Så vi måste skapa en uppsättning bilder i förhållandet 1:1 för vår APP med hjälp av alla verktyg.
  • Responsiv design: Webbappen ska vara responsiv för att fungera på olika skärmstorlekar.

Vad är Service Worker:

En tjänstearbetare (skript på klientsidan) är en proxy mellan din webbapp och den yttre sidan, som levererar push-meddelanden för vår webbapp och stöder cachelagring.

Service Worker körs oberoende av huvudjavascriptet. Så den har inte tillgång till DOM API. Den kan bara komma åt IndexedDB API, Hämta API, Cachelagrings-API. Men det kan kommunicera med huvudtråden med ett meddelande.

Tjänst som tillhandahålls av servicearbetare:

  • Avlyssning av HTTP-förfrågningar från din ursprungsdomän.
  • Ta emot push-meddelanden från din server.
  • Offline tillgänglighet för vår applikation

Servicearbetaren kontrollerar din applikation och kan manipulera dina förfrågningar, men den körs oberoende. Så av den anledningen måste ursprungsdomänen vara aktiverad med HTTPS för att undvika en man-in-the-middle-attack.

Vad är Manifest-filen

En manifestfil (manifest.json) har detaljer om vår PWA-app att berätta för webbläsaren.

  • namn: Namn på ansökan
  • short_name: Kort namn för vår ansökan. Om tillhandahållet
  • med både egenskapsnamn och short_name kommer webbläsaren att ta short_name.
  • beskrivning: Beskrivning för att beskriva vår applikation.
  • start_url: För att ange applikationens hemsida när vår PWA lanserades.
  • ikoner: Uppsättning bilder för PWA för hemskärmen, etc.
  • background_color: För att ställa in bakgrundsfärgen för startskärmen i vår PWA-applikation.
  • display: För att anpassa vårt webbläsargränssnitt så att det visas i vår PWA-app.
  • theme_color: Temafärg för PWA-appen.
  • scope: URL-räckvidd för vår ansökan att överväga för PWA. Förinställer platsen för manifestfilen som finns.
  • genvägar: Snabblänkar för vår PWA-applikation.

Konvertera webbapp till PWA

För demo-ändamålet har jag skapat en adminvista.com-webbplatsmappstruktur med statiska filer.

  • index.html – startsida
  • artiklar/
    • index.html – artikelsida
  • författare/
    • index.html – författares sida
  • verktyg/
    • index.html – verktygssida
  • erbjudanden/
    • index.html – erbjudanden sida

Om du redan har någon webbplats eller webbapp, försök att konvertera den till PWA genom att följa stegen nedan.

Skapa nödvändiga bilder för PWA

Ta först din applogotyp och beskära den i en storlek på 1:1 i 5 olika storlekar. jag har använt https://tools.crawlink.com/tools/pwa-icon-generator/ för att snabbt få olika bildstorlekar. Så du kan använda den också.

Skapa en manifestfil

För det andra, skapa en manifest.json-fil för din webbapplikation med dina appdetaljer. För demon har jag skapat en manifestfil för adminvista.com webbplats.

{
	"name": "adminvista.com",
	"short_name": "adminvista.com",
	"description": "adminvista.com 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": "adminvista.com - Authors",
			"url": "/authors",
			"icons": [{
				"src": "/assets/icon/icon-152x152.png",
				"sizes": "152x152"
			}]
		},
		{
			"name": "Tools",
			"short_name": "Tools",
			"description": "adminvista.com - Tools",
			"url": "https://adminvista.com.com/tools",
			"icons": [{
				"src": "/assets/icon/icon-152x152.png",
				"sizes": "152x152"
			}]
		},
		{
			"name": "Deals",
			"short_name": "Deals",
			"description": "adminvista.com - Deals",
			"url": "/deals",
			"icons": [{
				"src": "/assets/icon/icon-152x152.png",
				"sizes": "152x152"
			}]
		}
	]
}

Registrera Service-worker

skapa en skriptfil register-service-worker.js och service-worker.js i rotmappen.

Den första, register-service-worker.js är javascript-filen som kommer att köras på huvudtråden som kan komma åt DOM API. Men service-worker.js är ett serviceworker-skript som körs oberoende av huvudtråden och dess livslängd är också kort. Den körs närhelst händelser ringer servicearbetare och körs tills den avslutar processen.

Genom att kontrollera huvudtrådens javascript-fil kan du kontrollera om servicearbetaren är registrerad i den. om inte kan du registrera service worker-skriptet (service-worker.js).

klistra in nedanstående kodavsnitt i register-service-worker.js:

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

Klistra in kodavsnittet nedan i 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.
});

Vi koncentrerade oss inte på hur man aktiverar cache för offlinesupport. Vi pratar bara om hur man konverterar webbappar till PWA.

Lägg till manifestfil och skript i all head-taggen på din HTML-sida.

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

Uppdatera sidan efter att du lagt till. Nu kan du installera din applikation som nedan på mobil chrome.

På hemskärmen läggs appen till.

Om du använder WordPress. Prova att använda det befintliga PWA-konverteringspluginet. För vueJS eller reactJS kan du följa ovanstående metod eller använda de befintliga PWA npm-modulerna för att snabba upp din utveckling. Eftersom PWA npm-moduler redan är aktiverade med offline-stödcaching, etc.

Aktivera Push Notification

Webb-push-meddelanden skickas till webbläsaren för att få våra användare att interagera/interagera med vår applikation oftare. Vi kan aktivera det genom att använda

  • Notification API: Den används för att konfigurera hur vår push-notis ska visas för användaren.
  • Push API: Den används för att ta emot aviseringsmeddelanden som skickas från vår server till webbläsaren.

Det första steget för att aktivera push-meddelanden i vår applikation är att kontrollera Notification API och få tillåtelse från användaren att visa en notifikation. För det kopiera och klistra in kodavsnittet nedan i din 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);
        });
    }
};

Om allt gick som det ska. Du får ett meddelande från applikationen.

’Meddelande’ i fönstret talar om för oss att Notification API stöds i den webbläsaren. Notification.permission kommer att berätta att användaren har fått tillstånd att visa meddelandet. Om användaren tillåtit vår applikation kommer värdet att ”beviljas”. om användaren har avvisat kommer värdet att ”blockeras”.

Aktivera Firebase Cloud Messaging och Skapa prenumeration

Nu börjar den riktiga delen. För att skicka meddelanden från din server till användaren behöver vi en unik slutpunkt/prenumeration för varje användare. För det kommer vi att använda firebase molnmeddelanden.

Som ett första steg, skapa ett Firebase-konto genom att besöka den här länken https://firebase.google.com/ och tryck på kom igång.

  • Skapa ett nytt projekt med ett namn och tryck på fortsätt. Jag ska skapa den med namnet adminvista.com.
  • I nästa steg är Google Analytics aktiverat som standard. Du kan växla att vi inte behöver det nu och trycka på fortsätt. Du kan aktivera det senare i din firebase-konsol om du behöver det.
  • När projektet har skapats kommer det att se ut som nedan.
  • Gå sedan till projektinställningarna och klicka på molnmeddelanden och generera nycklar.

    Från stegen ovan har du 3 nycklar.

    • projektservernyckel
    • Webb-push-certifikat privat nyckel
    • Webb-push-certifikat offentlig nyckel

    Klistra nu in nedanstående kodavsnitt i 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();

    Klistra in kodavsnittet nedan i 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)
    });

    Nu är allt klart i front-end. Genom att använda prenumerationen kan du skicka push-meddelanden till din användare när du vill tills de inte nekades push-tjänsterna.

    Push från node.js Backend

    Du kan använda webb-push npm-modul för att göra det enklare.

    Exempel på utdrag för att skicka push-meddelanden från nodeJS-servern.

    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 adminvista.com-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 });
        });

    Ovanstående kod kommer att skicka ett pushmeddelande till prenumerationen. Push-händelsen i service-worker kommer att triggas.

    Push från PHP Backend

    För PHP-backend kan du använda webb-push-php kompositörspaket. Kontrollera exempelkoden för att skicka push-meddelanden nedan.

    <?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 adminvista.com-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)
    );

    Slutsats

    Jag hoppas att detta ger dig en idé om hur du konverterar webbapplikationer till PWA. Du kan kontrollera källkoden för den här artikeln här och demo det här. Jag har testat push-meddelandet genom att skicka det från backend med hjälp av exempelkod också.