Часть 3. Сохраняющиеся сообщения, обмен данными между Service Worker и веб-страницей
В части 1 мы настроили проект Firebase и получили сообщения на нашей веб-странице.
Во второй части мы добавили сервис-воркер, чтобы мы могли получать сообщения и показывать уведомления, когда веб-страница не сфокусирована или даже не открыта.
Но если страница не открыта и мы отправляем сообщения Firebase сервис-воркеру, было бы неплохо, если бы при открытии нашей веб-страницы отображались все сообщения, которые были получены, пока она была закрыта.
Для этого нам нужно сделать две вещи:
- Хранить сообщения, которые получает сервис-воркер;
- Когда веб-страница открыта, даже если это не текущая вкладка, отправьте на нее сообщения.
Если вам просто интересен чертов код, то финальная версия на github.
Хранение сообщений в сервис-воркере
Чтобы хранить сообщения таким образом, чтобы они не терялись даже при перезапуске браузера, мы будем использовать IndexedDB. И поскольку использовать необработанный API IndexedDB довольно неудобно, мы собираемся использовать Jake Archibalds idb, оболочку, которая дает нам интерфейс Promise.
(Знаю, в первой части я сказал, что я старомодный и не люблю использовать дополнительные слои, но idb действительно значительно упрощает использование IndexedDB.)
Нам нужно использовать IndexedDB только в service-worker.js
, поэтому мы добавляем импорт Javascript:
Добавьте функцию, которая создает базу данных и возвращает дескриптор базы данных:
Настройте прослушиватель, чтобы при активации сервисного работника он создавал базу данных:
Добавьте функцию, которая записывает сообщение в базу данных (обратите внимание, как она устанавливает атрибут messageId
, который мы определили как ключ в базе данных):
И, наконец, обновите функцию onBackgroundMessage, чтобы она сохраняла сообщение:
Итак, теперь любые сообщения, полученные сервис-воркером, записываются в базу данных. Но как нам вывести их на веб-страницу?
Сервисный работник для связи с веб-страницей
Чтобы получить наше сообщение Firebase на веб-страницу от работника службы, он может отправить его через клиента. Но на самом деле нам нужна двусторонняя связь, потому что веб-страница должна иметь возможность сказать: «Эй, я только что загрузилась, есть какие-нибудь сообщения?» к работнику службы.
Для этого воспользуемся BroadcastChannel. Поскольку мы хотим, чтобы это было как на веб-странице, так и в сервис-воркере, мы добавляем его в init-firebase.js
:
Настраиваем очень простое рукопожатие. Когда веб-страница загружается, она передает сообщение с атрибутом ready
. Когда сервис-воркер получает это, он рассылает все сообщения, которые у него есть в базе данных, используя атрибут message
.
Каждый раз, когда сервис-воркер получает сообщение от Firebase, он отправляет сообщение с атрибутом hello
. Если веб-страница получает это сообщение, она отвечает ready
.
Добавьте в service-worker.js
функцию, которая слушает канал и отвечает, если получает сообщение с ready
:
Также в service-worker.js
обновите функцию onBackgroundMessage
для отправки приветственной трансляции:
И, наконец, добавьте в webpage.js
функцию для обработки широковещательных сообщений hello
и message
, а также функцию для управления сервисным работником при загрузке страницы:
Краткое содержание
Вот и все! Мы связали Firebase Cloud Messaging с сервис-воркером, IndexedDB и BroadcastChannel, чтобы создать симпатичное маленькое приложение, которое вы можете использовать для отправки себе уведомлений из командной строки.
Для чего вы будете его использовать? Какие изменения вы внесете в сценарий sendmsg.sh
или стиль макета? Комментарий ниже!