我有一个SPA PWA React应用程序。它已在移动设备(Android + Chrome)上以独立模式安装并运行。
例如,该应用列出了人员,然后当您单击某个人时,它会使用/person
路线显示详细信息。
现在,我正在从服务器发送推送通知,并在应用程序附带的服务工作者中接收它们。该通知是关于某人的,当用户单击该通知时,我想打开该人的详细信息。
问题是:
/person
路由据我了解,可以从服务工作者notificationclick
事件处理程序中获得:
/person
不是物理路径,而且无论哪种方式-我都希望避免刷新页面)您可以监听显示给用户的通知的click
事件。在处理程序中,您可以通过push事件打开来自服务器的相应人员的URL。
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);
}
}
检查这些链接:
要回答我自己的问题:尽管我不太满意,但我已经使用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);
}
});
然后,在我的React应用程序的根目录中,即在我的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也可能是我不知道如何将其插入React框架的方法)
还有其他人,我还在寻找更好的解决方案。