请选择您遇到问题的任何浏览器:
Service Worker可以注册,但推送通知不会在Chrome 80.0.3987.132(官方内部版本)(64位)中弹出,但可以在Firefox Developers Edition中使用。我可以在Chrome浏览器的控制台中看到推送通知数据,但浏览器通知未显示。在Chrome的“应用程序”标签中,我可以在“推送消息和通知”部分中提取通知。
我希望在Chrome和其他浏览器(包括移动设备)中看到浏览器通知
打开通知的按钮将调用attemptToRegisterSW
功能。
const attemptToRegisterSW = async dispatch => {
if (
!('serviceWorker' in navigator) ||
!('PushManager' in window) ||
!('Notification' in window)
) {
dispatch(setNotificationMessage(`Sorry, your browser doesn't support push notifications`));
return;
}
try {
const components = await Fingerprint2.getPromise({
excludes: { webdriver: true, cpuClass: true, fonts: true },
});
const fingerPrint = Fingerprint2.x64hash128(
components.map(component => component.value).join(''),
31,
);
const register = await navigator.serviceWorker.register('/service-worker.js', { scope: '/' });
await navigator.serviceWorker.ready;
const permissionResult = await askPermission();
if (permissionResult === 'granted') {
const subscription = await register.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(publicVapidKey),
});
const token = getItemFromLocalStorage(INNERYOU_JWT);
if (fingerPrint) {
const req = await fetch('/api/alerts/subscribe', {
method: 'POST',
headers: {
'content-type': 'application/json',
accept: 'application/json',
authorization: `Bearer ${token}`,
},
body: JSON.stringify({ subscription, fingerPrint }),
});
if (req.status === 201) dispatch(setNotificationMessage(`Push notifications turned on`));
}
} else {
dispatch(
setNotificationMessage(
`Push notifications are either blocked or denied, please adjust your browser settings`,
),
);
}
} catch (error) {
dispatch(
setNotificationMessage(`Error while turning on push notifications, please try again.`),
);
console.error(`Error while registering serviceWorker ${error}`);
}
};
检查是否已授予权限
const getNotificationPermissionState = async () => {
try {
if (navigator.permissions) {
const navigatorPermissions = await navigator.permissions.query({ name: 'notifications' });
return navigatorPermissions.state;
}
return await Notification.permission;
} catch (error) {
console.error(`Error while getting notification status ${error}`);
throw new Error("We weren't granted permission.");
}
};
询问用户权限
export const askPermission = async () => {
try {
const notificationStatus = await getNotificationPermissionState();
if (notificationStatus === 'granted') {
return notificationStatus;
}
return await Notification.requestPermission();
} catch (error) {
console.error(`Error while requesting notification permission ${error}`);
throw new Error("We weren't granted permission.");
}
};
import webpush from 'web-push';
const publicVapidKey = process.env.PUBLICVAPIDKEY;
const privateVapidKey = process.env.PRIVATEVAPIDKEY;
webpush.setVapidDetails('mailto:noresponse@inneryou.io', publicVapidKey, privateVapidKey);
alertRouter.post('/subscribe', verifyUserAuthStatus, async (req, res, next) => {
try {
const userId = res?.locals?.user?.id;
const { subscription, fingerPrint } = req.body;
if (!fingerPrint || !subscription) {
res.status(400);
res.locals.error = 'Bad Request';
throw new Error('Bad Request');
}
const isExistingDevice: DeviceModel = await Devices.findOne({
fingerPrint,
'subscription.keys.auth': subscription.keys.auth,
});
let newDevice: DeviceModel = null;
if (!isExistingDevice) {
newDevice = await Devices.create({ user: userId, fingerPrint, subscription });
}
if (newDevice) {
await User.findByIdAndUpdate(userId, {
$push: {
devices: newDevice._id,
},
});
}
res.status(201).json({});
const notification = {
title: 'Push Notification',
body: 'Subscribed to push notifications',
icon: '',
};
const payload = buildCommonMessage(notification);
const devices: DeviceModel[] = await Devices.find({ user: userId }).lean();
for (const device of devices) {
await webpush.sendNotification(device.subscription, payload).catch(err => {
if (err.statusCode === 410) {
// DELETE DEVICE IF SUBSCRIPTION IS INVALID
console.error(`Deleting invalid subscription: ${err}`);
return Devices.findByIdAndRemove(device._id);
} else {
console.error(`Subscription is no longer valid: ${err}`);
}
});
}
} catch (error) {
console.error(`Error with push notification ${error}`);
}
});
export const buildCommonMessage = ({ title, body, icon }: CommonMessage): any => {
return JSON.stringify({
title: title,
body: body,
icon: icon || NOTIFICATION_IMAGE_URL,
});
};
/* eslint-disable no-restricted-globals */
self.addEventListener('push', (e) => {
console.log('[Service Worker] Push Received.');
const data = e.data.json();
const title = data.title || 'InnerYou Notification';
self.registration.showNotification(title, {
body: data.body,
icon: data.icon,
});
});