Как активировать маршрут реакции и передать данные от обслуживающего работника? - PullRequest
4 голосов
/ 10 января 2020

У меня есть приложение SPA PWA React.
Оно установлено и работает в автономном режиме на мобильном устройстве (Android + Chrome).

Допустим, в приложении перечислены люди, а затем, когда вы нажимаете на человека он отображает детали, используя /person маршрут.

Теперь я отправляю уведомления pu sh с сервера и получаю их в сервисном работнике, прикрепленном к приложению. Уведомление о человеке, и я хочу открыть его данные, когда пользователь нажимает на уведомление.

Вопрос:

  • как мне активировать маршрут /person в моем приложении от работника службы
  • и передачи данных (например, идентификатор человека или объект персоны)
  • без перезагрузки приложения

Из того, что я понимаю, из обслуживающий работник notificationclick обработчик событий я могу:

  • сосредоточиться на приложении (но как мне передать данные и активировать маршрут)
  • открыть URL (но /person это не физический маршрут, и в любом случае - я хочу избежать обновления страницы)

Ответы [ 2 ]

1 голос
/ 15 января 2020

Чтобы ответить на мой собственный вопрос: я использовал IndexedDB (не могу использовать localStorage, поскольку он синхронный) для связи между SW и PWA, хотя я не слишком доволен этим.

Это примерно как выглядит мой код работника сервиса (я использую библиотеку idb):

self.addEventListener('notificationclick', function(event) {
    const notif = event.notification;
    notif.close();
    if (notif.data) {
        let db;
        let p = idb.openDB('my-store', 1, {
            upgrade(db) {
                db.createObjectStore(OBJSTORENAME, {
                    keyPath: 'id'
                });
            }
        }).then(function(idb) {
            db = idb;
            return db.clear(OBJSTORENAME);
        }).then(function(rv) {            
            return db.put(OBJSTORENAME, notif.data);
        }).then(function(res) {
            clients.openWindow('/');
        }).catch(function(err) {
            console.log("Error spawning notif", err);
        });
        event.waitUntil(p);
    }
});

, а затем в root моего приложения реагирования ie в моем компоненте AppNavBar я всегда проверяю, есть ли кое-что показать:

componentWillMount() {
    let self = this;
    let db;
    idb.openDB('my-store', 1)
    .then(function (idb) {
        db = idb;            
        return db.getAll(OBJSTORENAME);
    }).then(function (items) {            
        if (items && items.length) {
            axios.get(`/some-additional-info-optional/${items[0].id}`).then(res => {
                if (res.data && res.data.success) {
                    self.props.history.push({
                        pathname: '/details',
                        state: {
                            selectedObject: res.data.data[0]
                        }
                    });
                }
            });
            db.clear(OBJSTORENAME)
            .then()
            .catch(err => {
                console.log("error clearing ", OBJSTORENAME);
            });
        }
    }).catch(function (err) {
        console.log("Error", err);
    });
}

Играли с clients.openWindow('/?id=123'); и clients.openWindow('/#123');, но это странно, иногда приложение зависало, поэтому я вернулся к подходу IndexedDB. (clients.postMessage также может быть способом к go, хотя я не уверен, как подключить это к платформе реагирования)

HTH, и я все еще ищу лучшее решение.

1 голос
/ 13 января 2020

Вы можете прослушать событие click для Уведомления, которое вы показываете пользователю. А в обработчике вы можете открыть URL для соответствующего человека, который приходит с вашего сервера с событием pu sh.

notification.onclick = function(event) {
  event.preventDefault(); 

  // suppose you have an url property in the data
  if (event.notification.data.url) {

      self.clients.openWindow(event.notification.data.url);
  }
}

Проверьте эти ссылки:

...