按照这个示例,我了解到 PWA 可以打开 url,但如何使用推送通知来启动应用程序本身呢?不是在浏览器中打开,而是全屏版本的 PWA。
这由浏览器控制。此外,在决定打开一个窗口时,可能值得检查所需的目标URL是否已经在另一个选项卡/窗口中打开,以便根据情况进行焦点或打开。 点击此处获取一些代码示例。
例如,在Chrome中,如果用户使用manifest中的“standalone”将Web应用程序添加到主屏幕,则每当用户单击Web应用程序图标时,它都将在没有URL栏的情况下打开。
当接收到推送消息并且已打开同一Web应用程序时,如果用户最近(在过去的10天内)从主屏幕图标打开了Web应用程序,则不会显示URL栏。如果用户在该时间段内没有使用主屏幕图标,则通知单击将显示URL栏。
请参见此处的Chrome问题的更多信息:
具体来说:
Web应用程序必须添加到主屏幕,能够以独立模式打开,并且在过去的10天内已从主屏幕打开。如果不满足任何这些条件,则通知将回退到现有行为。
值得注意的是,PWA与浏览器本身并不是正确的思考方式。您总是在浏览器中启动,只是以不同的模式,“独立”与“浏览器”等。
PWA(渐进式Web应用程序)主要是一种描述使用一组API来利用新的Web技术(例如服务工作者,推送,Web应用程序清单等)提供良好用户体验的术语。
我已成功使用Chrome 69.
在这个例子中,它是一个子应用程序(www.example.com/application).
简而言之:仔细检查路径!
我还遇到了一些问题,如果我从推送通知启动应用程序时,会出现未加载的cookie(登录信息),它可以打开,但未登录。如果您关闭它并点击之前添加在主屏幕上的应用程序图标,则应用程序将已经登录。
我使用以下方法实现(请参阅注释):
1)serviceworker.js
self.addEventListener('notificationclick', function (event)
{
//For root applications: just change "'./'" to "'/'"
//Very important having the last forward slash on "new URL('./', location)..."
const rootUrl = new URL('./', location).href;
event.notification.close();
event.waitUntil(
clients.matchAll().then(matchedClients =>
{
for (let client of matchedClients)
{
if (client.url.indexOf(rootUrl) >= 0)
{
return client.focus();
}
}
return clients.openWindow(rootUrl).then(function (client) { client.focus(); });
})
);
});
2) manifest.json
{
"short_name": "AppNickName",
"name": "ApplicationName",
"icons": [
{
"src": "./icon.png",
"sizes": "36x36",
"type": "image/png",
"density": 0.75
}
],
"start_url": "./", //This matters
"display": "standalone", //This also matters
"gcm_sender_id": "103953800507", //FCM always uses this number (April 2019)
"background_color": "#c8c8c8",
"theme_color": "#c8c8c8",
"orientation": "any"
}
以下内容摘自Jake Archibald的emojoy演示:
self.addEventListener('notificationclick', event => {
const rootUrl = new URL('/', location).href;
event.notification.close();
// Enumerate windows, and call window.focus(), or open a new one.
event.waitUntil(
clients.matchAll().then(matchedClients => {
for (let client of matchedClients) {
if (client.url === rootUrl) {
return client.focus();
}
}
return clients.openWindow("/");
})
);
});
我在这里找到了一个对我有用的解决方案。
只需将以下内容添加到您的服务工作者中:
self.addEventListener('notificationclick', function(event) {
console.log('On notification click: ', event.notification.tag);
// Android doesn't close the notification when you click on it
// See: http://crbug.com/463146
event.notification.close();
// This looks to see if the current is already open and
// focuses if it is
event.waitUntil(
clients.matchAll({
type: "window"
})
.then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url == '/' && 'focus' in client)
return client.focus();
}
if (clients.openWindow) {
return clients.openWindow('/');
}
})
);
});
可以在此处找到更新版本: https://web.dev/push-notifications-common-notification-patterns/
当有可能时,我们应该将焦点放在一个窗口上,而不是每次用户点击通知时都打开一个新窗口。
在我们看如何实现这一点之前,值得强调的是,这只适用于您站点上的页面。这是因为我们只能看到属于我们站点的已打开页面。这样可以防止开发人员能够查看用户正在浏览的所有站���。
以前的例子中,我们将修改代码以查看是否已经打开了 /demos/notification-examples/example-page.html。
const urlToOpen = new URL(examplePage, self.location.origin).href;
const promiseChain = clients
.matchAll({
type: 'window',
includeUncontrolled: true,
})
.then((windowClients) => {
let matchingClient = null;
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
if (windowClient.url === urlToOpen) {
matchingClient = windowClient;
break;
}
}
if (matchingClient) {
return matchingClient.focus();
} else {
return clients.openWindow(urlToOpen);
}
});
event.waitUntil(promiseChain);