Как преобразовать WebApp в PWA с помощью push-уведомлений
Опубликовано: 2022-03-20В этой статье мы увидим, как преобразовать веб-приложение или веб-сайт в PWA с помощью push-уведомлений с помощью Firebase Cloud Messaging.
В современном мире большинство веб-приложений преобразуются в PWA (прогрессивное веб-приложение), поскольку оно предоставляет такие функции, как автономная поддержка, push-уведомления, фоновая синхронизация. Функции PWA делают наше веб-приложение более похожим на родное приложение и обеспечивают богатый пользовательский интерфейс.
Например, такие крупные компании, как Twitter и Amazon, преобразовали свои веб-приложения в PWA для большего вовлечения пользователей.
Что такое ПВА?
PWA = (веб-приложение) + (некоторые встроенные функции приложения)
PWA — это ваше же веб-приложение (HTML+CSS+JS). Оно работает так же, как и ваше веб-приложение, во всех браузерах, как и раньше. Но он может иметь встроенные функции, когда ваш сайт загружается в современном браузере. Это делает ваше веб-приложение более мощным, чем раньше, а также делает его более масштабируемым, поскольку мы можем выполнять предварительную выборку и кэширование ресурсов во внешнем интерфейсе, что уменьшает количество запросов к вашему внутреннему серверу.
Чем PWA отличается от веб-приложения
- Возможность установки : ваше веб-приложение может быть установлено как родное приложение.
- Progressive : работает так же, как ваше веб-приложение, но с некоторыми встроенными функциями.
- Нативное приложение : после установки пользователь может использовать и перемещаться по веб-приложению как нативное.
- Легкий доступ : в отличие от нашего веб-приложения, нашим пользователям не нужно вводить веб-адреса каждый раз, когда они посещают. После установки его можно открыть одним нажатием.
- Кэширование приложений . До PWA единственным механизмом кеширования, реализованным в нашем веб-приложении, было использование кеша HTTP, доступного только для браузера. Но с PWA мы можем кэшировать вещи, используя сам код на стороне клиента, который недоступен в веб-приложении.
- Публикация в магазине (App/Play) : PWA можно публиковать в Google Play Store и IOS App Store.
Преобразование вашего приложения в PWA сделает его только более мощным.
Почему бизнес должен рассмотреть PWA
В то время как большинство наших клиентов обращаются к нам и просят сначала разработать решение для веб-приложений, а затем они запрашивают приложения для Android и iOS. Все, что мы собираемся сделать, это создать ту же функциональность в веб-приложении для приложения Android/IOS отдельной командой, что требует больше затрат на разработку и больше времени для выхода на рынок.
Но у некоторых клиентов ограниченный бюджет, или некоторые клиенты могут подумать, что время выхода на рынок важнее для их продукта.
Большинство требований клиента могут быть удовлетворены самими функциями PWA. Для них мы предлагаем только PWA и даем им идею преобразовать свое PWA в приложение для Android с помощью TWA, если они хотят развернуть его в Playstore.
Если вашим требованиям действительно нужны встроенные функции приложения, которые не может удовлетворить PWA. Клиенты могут идти и разрабатывать оба приложения по своему желанию. Но даже в этом сценарии. Они могут развернуть PWA в магазине игр, пока разработка Android не будет завершена.
Пример: Титан Eyeplus
Первоначально они разработали приложение PWA и развернули его в магазине игр с помощью TWA (Trusted Web Activity). Как только они завершили разработку своего приложения для Android. Они развернули свое настоящее Android-приложение в игровом магазине. Они достигли как времени выхода на рынок с помощью PWA, так и стоимости разработки.
Функции PWA
PWA предоставляет нашим веб-приложениям собственные функции, подобные приложениям.
Основные особенности:
- Устанавливаемое: веб-приложение, устанавливаемое как родное приложение.
- Кэширование: Возможно кэширование приложений, что обеспечивает автономную поддержку нашего приложения.
- Push-уведомление: Push-уведомление может быть отправлено с нашего сервера, чтобы привлечь наших пользователей на наш веб-сайт.
- Геозоны: приложение может получать уведомления о событии при изменении местоположения устройства.
- Запрос платежа: Включите оплату в своем приложении с удобным пользовательским интерфейсом, таким как нативное приложение.
И многие другие функции появятся в будущем.
Другие особенности:
- Ярлыки: быстро доступные URL-адреса, добавленные в файл манифеста.
- Web Share API: пусть ваше приложение получает общие данные из других приложений.
- Badge API: чтобы показать количество уведомлений в установленном PWA.
- API периодической фоновой синхронизации: сохраняет данные пользователя до тех пор, пока он не подключится к сети.
- Средство выбора контактов: используется для выбора контактов с мобильного телефона пользователя.
- Средство выбора файлов: используется для доступа к файлу в локальной системе/мобильном устройстве.
Преимущество PWA перед родным приложением
Нативное приложение работает лучше, чем PWA, и имеет больше функций, чем PWA. Но все же у него есть некоторые преимущества перед нативным приложением.
- PWA работает на кроссплатформенных платформах, таких как Android, IOS, Desktop.
- Это снижает ваши затраты на разработку.
- Простое развертывание функций по сравнению с собственным приложением.
- Легко обнаружить, потому что PWA (веб-сайт) оптимизирован для SEO.
- Безопасен, потому что работает только на HTTPS
Недостатки PWA по сравнению с родным приложением
- Доступны ограниченные функциональные возможности по сравнению с родным приложением.
- Не гарантируется, что функции PWA будут поддерживать все устройства.
- Бренд PWA низок, потому что он недоступен в магазине приложений или магазине игр.
Вы можете развернуть PWA как приложение для Android в магазине игр с помощью доверенной веб-активности Android (TWA). Это поможет вашему брендингу.
Вещи, необходимые для преобразования веб-приложения в PWA
Для преобразования любого веб-приложения или веб-сайта в PWA.
- Service-Worker: ядро любого приложения PWA для кэширования, push-уведомлений, прокси для наших запросов.
- Файл манифеста: содержит сведения о вашем веб-приложении. Раньше он загружал наше приложение как родное приложение на главном экране.
- Логотип приложения: высококачественное изображение 512 x 512 пикселей для значка вашего приложения. Логотип приложения, необходимый для PWA на главном экране, заставке и т. д. Таким образом, мы должны создать набор изображений с соотношением сторон 1:1 для нашего приложения, используя любые инструменты.
- Отзывчивый дизайн: веб-приложение должно реагировать на работу на разных размерах экрана.
Что такое сервис-воркер:
Сервисный работник (сценарий на стороне клиента) — это прокси-сервер между вашим веб-приложением и внешней стороной, доставляющий push-уведомления для нашего веб-приложения и поддерживающий кэширование.
Service Worker работает независимо от основного javascript. Поэтому у него нет доступа к DOM API. Он может получить доступ только к IndexedDB API, Fetch API, Cache Storage API. Но он может общаться с основным потоком с помощью сообщения.
Услуга предоставляется сервисным работником:
- Перехват HTTP-запросов с исходного домена.
- Получайте Push-уведомления с вашего сервера.
- Оффлайн доступность нашего приложения
Service Worker контролирует ваше приложение и может манипулировать вашими запросами, но работает независимо. По этой причине исходный домен должен быть включен с HTTPS, чтобы избежать атаки «человек посередине».
Что такое файл манифеста
Файл манифеста (manifest.json) содержит сведения о нашем приложении PWA, которые нужно сообщить браузеру.
- имя: Имя приложения
- short_name: короткое имя для нашего приложения. Если предусмотрено
- как с именем свойства, так и с short_name, браузер примет short_name.
- description: Описание для описания нашего приложения.
- start_url: указать домашнюю страницу приложения при запуске нашего PWA.
- иконки: Набор изображений для PWA для главного экрана и т. д.
- background_color: установить цвет фона заставки в нашем приложении PWA.
- display: чтобы настроить пользовательский интерфейс браузера для отображения в нашем приложении PWA.
- theme_color: цвет темы приложения PWA.
- scope: область URL нашего приложения, которую следует учитывать для PWA. По умолчанию используется расположение файла манифеста.
- ярлыки: Быстрые ссылки для нашего приложения PWA.
Преобразование веб-приложения в PWA
Для демонстрации я создал структуру папок веб-сайта Geekflare со статическими файлами.
- index.html — домашняя страница
- статьи/
- index.html — страница статей
- авторы/
- index.html — страница авторов
- инструменты/
- index.html — страница инструментов
- сделок/
- index.html — страница сделок
Если у вас уже есть веб-сайт или веб-приложение, попробуйте преобразовать его в PWA, выполнив следующие действия.
Создайте необходимые образы для PWA
Во-первых, возьмите логотип вашего приложения и обрежьте его в соотношении 1:1 в 5 разных размерах. Я использовал https://tools.crawlink.com/tools/pwa-icon-generator/, чтобы быстро получать изображения разных размеров. Так что вы тоже можете его использовать.
Создать файл манифеста
Во-вторых, создайте файл manifest.json для своего веб-приложения с подробной информацией о вашем приложении. Для демонстрации я создал файл манифеста для веб-сайта Geekflare.
{ "имя": "Geekflare", "short_name": "Geekflare", "description": "Geekflare выпускает высококачественные статьи о технологиях и финансах, создает инструменты и API, помогающие бизнесу и людям расти.", "start_url": "/", "значки": [{ "src": "активы/значок/значок-128x128.png", "размеры": "128x128", "тип": "изображение/png" }, { "src": "активы/значок/значок-152x152.png", "размеры": "152x152", "тип": "изображение/png" }, { "src": "активы/значок/значок-192x192.png", "размеры": "192x192", "тип": "изображение/png" }, { "src": "активы/значок/значок-384x384.png", "размеры": "384x384", "тип": "изображение/png" }, { "src": "активы/значок/значок-512x512.png", "размеры": "512x512", "тип": "изображение/png" }], "background_color": "#EDF2F4", "дисплей": "автономный", "тема_цвет": "#B20422", "сфера": "/", "ярлыки": [{ "имя": "Статьи", "short_name": "Статьи", "description": "1595 статей по безопасности, системному администрированию, цифровому маркетингу, облачным вычислениям, разработке и многим другим темам.", "url": "/ статьи", "значки": [{ "src": "/assets/icon/icon-152x152.png", "Размеры": "152x152" }] }, { "имя": "Авторы", "short_name": "Авторы", "description": "Geekflare - Авторы", "url": "/авторы", "значки": [{ "src": "/assets/icon/icon-152x152.png", "Размеры": "152x152" }] }, { "имя": "Инструменты", "short_name": "Инструменты", "description": "Geekflare - Инструменты", "url": "/инструменты", "значки": [{ "src": "/assets/icon/icon-152x152.png", "Размеры": "152x152" }] }, { "name": "Сделки", "short_name": "Сделки", "description": "Geekflare — Предложения", "url": "/сделки", "значки": [{ "src": "/assets/icon/icon-152x152.png", "Размеры": "152x152" }] } ] }
Регистрация Сервис-воркер
создайте файл сценария register-service-worker.js и service-worker.js в корневой папке.
Первый, register-service-worker.js, — это файл javascript, который будет выполняться в основном потоке, имеющем доступ к DOM API. Но service-worker.js — это скрипт сервисного работника, который работает независимо от основного потока, и его время жизни также короткое. Он запускается всякий раз, когда события вызывают сервисных рабочих, и запускается до тех пор, пока не завершит процесс.
Проверив файл javascript основного потока, вы можете проверить, зарегистрирован ли в нем сервисный работник. если нет, вы можете зарегистрировать скрипт сервисного работника (service-worker.js).
вставьте приведенный ниже фрагмент в register-service-worker.js:
если ("serviceWorker" в навигаторе) { window.addEventListener («загрузить», функция () { navigator.serviceWorker.register('/service-worker.js'); }); }
Вставьте приведенный ниже фрагмент в service-worker.js.
self.addEventListener('install', (event) => { // событие при установке сервис-воркера console.log('установить', событие); self.skipWaiting(); }); self.addEventListener('activate', (event) => { // событие при активации сервис-воркера console.log('активировать', событие); вернуть self.clients.claim(); }); self.addEventListener('fetch', function(event) { // перехватчик HTTP-запросов event.respondWith(fetch(event.request)); // отправляем все HTTP-запросы без какой-либо логики кэширования /*событие.ответить( caches.match(event.request).then(function(response) { вернуть ответ || выборка(событие.запрос); }) );*/ // кэшируем новый запрос. если уже в кеше служит с кешем. });
Мы не сосредоточились на том, как включить кеш для автономной поддержки. Мы говорим только о том, как конвертировать веб-приложения в PWA.

Добавьте файл манифеста и скрипт во все теги заголовка вашей HTML-страницы.
<link rel="manifest" href="/manifest.json"> <script src="/register-service-worker.js"></script>
Обновите страницу после добавления. Теперь вы можете установить свое приложение, как показано ниже, на мобильный Chrome.

Приложение добавляется на главный экран.

Если вы используете WordPress. Попробуйте использовать существующий плагин конвертера PWA. Для vueJS или reactJS вы можете следовать описанному выше методу или использовать существующие модули PWA npm для ускорения разработки. Поскольку модули PWA npm уже включены с автономным кэшированием поддержки и т. д.
Включить push-уведомление
Веб-push-уведомления отправляются в браузер, чтобы наши пользователи чаще взаимодействовали с нашим приложением. Мы можем включить его, используя
- Notification API: он используется для настройки того, как наше push-уведомление должно отображаться пользователю.
- Push API: он используется для получения уведомлений, отправленных с нашего сервера в браузер.
Первым шагом для включения push-уведомлений в нашем приложении является проверка Notification API и получение разрешения от пользователя на отображение уведомления. Для этого скопируйте и вставьте приведенный ниже фрагмент в свой файл register-service-worker.js.
if ('Уведомление' в окне && Notification.permission != 'предоставлено') { console.log('Запросить разрешение у пользователя') Notification.requestPermission (статус => { console.log('Статус:'+статус) displayNotification('Уведомление включено'); }); } const displayNotification = уведомлениеЗаголовок => { console.log('отображать уведомление') если (Notification.permission == 'предоставлено') { navigator.serviceWorker.getRegistration().then(reg => { console.log(reg) постоянные параметры = { body: 'Спасибо, что разрешили push-уведомление!', значок: '/assets/icons/icon-512x512.png', вибрировать: [100, 50, 100], данные: { dateOfArrival: Дата.сейчас(), первичный ключ: 0 } }; reg.showNotification (notificationTitle, параметры); }); } };
Если все прошло правильно. Вы получите уведомление от приложения.


«Уведомление» в окне сообщит нам, что API уведомлений поддерживается в этом браузере. Notification.permission сообщит, что пользователю разрешено показывать уведомление. Если пользователь разрешил наше приложение, значение будет «предоставлено». если пользователь отклонил значение, оно будет «заблокировано».
Включить облачный обмен сообщениями Firebase и создать подписку
Теперь начинается настоящая часть. Для отправки уведомлений с вашего сервера пользователю нам нужна уникальная конечная точка/подписка для каждого пользователя. Для этого мы будем использовать облачный обмен сообщениями Firebase.
В качестве первого шага создайте учетную запись Firebase, перейдя по этой ссылке https://firebase.google.com/, и нажмите «Начать».
- Создайте новый проект с именем и нажмите «Продолжить». Я собираюсь создать его под названием Geekflare.
- На следующем шаге Google Analytics включен по умолчанию. Вы можете переключить, что нам это сейчас не нужно, и нажать «Продолжить». Вы можете включить его позже в консоли Firebase, если вам нужно.
- После создания проекта он будет выглядеть так, как показано ниже.

Затем перейдите в настройки проекта и нажмите облачный обмен сообщениями и сгенерируйте ключи.

Из вышеперечисленных шагов у вас есть 3 ключа.
- ключ сервера проекта
- Закрытый ключ веб-сертификатов push-уведомлений
- Открытый ключ веб-сертификатов push-уведомлений
Теперь вставьте приведенный ниже фрагмент в register-service-worker.js:
const updateSubscriptionOnYourServer = подписка => { console.log('Напишите здесь свой ajax-код, чтобы сохранить подписку пользователя в вашей БД', подписка); // напишите свой собственный метод запроса ajax, используя fetch, jquery, axios, чтобы сохранить подписку на вашем сервере для последующего использования. }; const subscribeUser = асинхронный () => { const swRegistration = await navigator.serviceWorker.getRegistration(); const applicationServerPublicKey = 'BOcTIipY07N4Y63Y-9r7NMoJHofmCzn3Pu9g-LMsgIMGH4HVr42_LW9ia0lMr68TsTLKS3UcdkE3IcC52hJDYsY'; // вставляем открытый ключ сертификата webpush const applicationServerKey = urlB64ToUint8Array (applicationServerPublicKey); swRegistration.pushManager.subscribe({ userVisibleOnly: правда, ApplicationServerKey }) .тог((подписка) => { console.log('Пользователь подписан недавно:', подписка); updateSubscriptionOnServer (подписка); }) .catch((ошибка) => { если (Notification.permission === 'отказано') { console.warn('Отказано в доступе к уведомлениям') } еще { console.error('Не удалось подписаться на пользователя: ', ошибка) } }); }; const urlB64ToUint8Array = (base64String) => { const padding = '='.repeat((4 - base64String.length % 4) % 4) const base64 = (base64String + заполнение) .replace(/\-/g, '+') .заменить(/_/г, '/') const rawData = window.atob(base64); const outputArray = новый Uint8Array (rawData.length); for (пусть я = 0; я < rawData.length; ++ я) { outputArray[i] = rawData.charCodeAt(i); } вернуть выходной массив; }; константа checkSubscription = асинхронная () => { const swRegistration = await navigator.serviceWorker.getRegistration(); swRegistration.pushManager.getSubscription() .тогда (подписка => { если (!!подписка) { console.log('Пользователь уже подписан.'); updateSubscriptionOnYourServer (подписка); } еще { console.log('Пользователь НЕ подписан. Подпишите пользователя заново'); подписатьсяПользователь(); } }); }; проверитьПодписка();
Вставьте приведенный ниже фрагмент в service-worker.js.
self.addEventListener('push', (событие) => { const json = JSON.parse(event.data.text()) console.log('Отправить данные', event.data.text()) self.registration.showNotification (json.header, json.options) });
Теперь все настроено в передней части. Используя подписку, вы можете отправлять push-уведомления своему пользователю в любое время, пока им не будет отказано в push-сервисах.
Отправка из бэкэнда node.js
Вы можете использовать модуль web-push npm, чтобы упростить задачу.
Пример фрагмента для отправки push-уведомления с сервера nodeJS.
const webPush = require('web-push'); // pushSubscription — это не что иное, как подписка, которую вы отправили из вашего внешнего интерфейса, чтобы сохранить ее в БД const pushSubscription = {"endpoint":"https://updates.push.services.mozilla.com/wpush/v2/gAAAAABh2…E0mTFsHtUqaye8UCoLBq8sHCgo2IC7UaafhjGmVCG_SCdhZ9Z88uGj-uwMcg","keys":{"auth":"qX6AMD5JWbu41cFWE3Lk8wd","p52Lk8wd" :"BLxHw0IMtBMzOHnXgPxxMgSYXxwzJPxpgR8KmAbMMe1-eOudcIcUTVw0QvrC5gWOhZs-yzDa4yKooqSnM3rnx7Y"}}; //открытый ключ ваших веб-сертификатов const vapidPublicKey = 'BOcTIipY07N4Y63Y-9r7NMoJHofmCzn3Pu9g-LMsgIMGH4HVr42_LW9ia0lMr68TsTLKS3UcdkE3IcC52hJDYsY'; //закрытый ключ вашего веб-сертификата const vapidPrivateKey = 'закрытый ключ веб-сертификата'; var полезная нагрузка = JSON.stringify({ "опции": { "body": "Тестирование push-уведомлений PWA с бэкенда", "значок": "/assets/icon/icon-152x152.png", "icon": "/assets/icon/icon-152x152.png", "вибрировать": [100, 50, 100], "данные": { "идентификатор": "458", }, "действия": [{ "действие": "просмотр", "название": "Просмотреть" }, { "действие": "закрыть", "название": "Закрыть" }] }, "header": "Уведомление от демонстрации Geekflare-PWA" }); параметры переменной = { vapidDetails: { тема: 'mailto:[электронная почта защищена]', публичный ключ: vapidPublicKey, приватный ключ: vapidPrivateKey }, Срок жизни: 60 }; webPush.sendNotification( pushПодписка, полезная нагрузка, опции ).затем (данные => { return res.json({status: true, message: 'Уведомление отправлено'}); }).поймать(ошибка => { вернуть res.json ({статус: ложь, сообщение: ошибка}); });
Приведенный выше код отправит push-уведомление подписке. Событие push в сервис-воркере будет запущено.
Push из бэкенда PHP
Для серверной части PHP вы можете использовать пакет композитора web-push-php. Проверьте приведенный ниже пример кода для отправки push-уведомлений.
<?php if ( !defined('БАЗОВАЯ ПУТЬ')) 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":"qX6AMD6JWbu41cFWE3 ":"BLxHw0IMtBMzOHnXgPxxMgSYXxwzJPxpgR8KmAbMMe1-eOudcIcUTVw0QvrC5gWOhZs-yzDa4yKooqSnM3rnx7Y"}}'; $payloadData = массив ( 'опции' => массив ( 'body' => 'Тестирование push-уведомлений PWA с бэкенда', 'значок' => '/assets/icon/icon-152x152.png', 'icon' => '/assets/icon/icon-152x152.png', 'вибрировать' => множество ( 0 => 100, 1 => 50, 2 => 100, ), 'данные' => множество ( 'id' => '458', ), 'действия' => множество ( 0 => множество ( 'действие' => 'просмотр', 'название' => 'Вид', ), 1 => множество ( 'действие' => 'закрыть', 'название' => 'Закрыть', ), ), ), 'header' => 'Уведомление от Geekflare-PWA Demo', ); // авторизация $ авторизация = [ 'GCM' => 'приватный ключ вашего проекта', // устарел и необязателен, он здесь только из соображений совместимости 'БЕЗУМНЫЙ' => [ 'subject' => 'mailto:[email protected]', // может быть mailto: или адрес вашего веб-сайта 'publicKey' => 'BOcTIipY07N4Y63Y-9r7NMoJHofmCzn3Pu9g-LMsgIMGH4HVr42_LW9ia0lMr68TsTLKS3UcdkE3IcC52hJDYsY', // (рекомендуется) несжатый открытый ключ P-256, закодированный в Base64-URL 'privateKey' => 'ваш закрытый ключ веб-сертификата', // (рекомендуется) на самом деле секретный множитель закрытого ключа, закодированный в Base64-URL ], ]; $webPush = новый WebPush($auth); $subsrciptionData = json_decode($subsrciptionJson,true); // вебпуш 6.0 $webPush->sendOneNotification( Подписка::создать($subsrciptionData), json_encode($payloadData) // необязательный (по умолчанию null) );
Вывод
Я надеюсь, что это дало вам представление о преобразовании веб-приложений в PWA. Вы можете проверить исходный код этой статьи здесь и продемонстрировать его здесь. Я также протестировал push-уведомление, отправив его из бэкэнда с помощью примера кода.