Часть 3. Сохраняющиеся сообщения, обмен данными между Service Worker и веб-страницей

В части 1 мы настроили проект Firebase и получили сообщения на нашей веб-странице.

Во второй части мы добавили сервис-воркер, чтобы мы могли получать сообщения и показывать уведомления, когда веб-страница не сфокусирована или даже не открыта.

Но если страница не открыта и мы отправляем сообщения Firebase сервис-воркеру, было бы неплохо, если бы при открытии нашей веб-страницы отображались все сообщения, которые были получены, пока она была закрыта.

Для этого нам нужно сделать две вещи:

  1. Хранить сообщения, которые получает сервис-воркер;
  2. Когда веб-страница открыта, даже если это не текущая вкладка, отправьте на нее сообщения.

Если вам просто интересен чертов код, то финальная версия на 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 или стиль макета? Комментарий ниже!