您好,在我的nextjs项目中,我将添加firebase推送通知。我第一次这样做,遇到了一些麻烦。我的代码:
next.config.js
...
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
...
if (!isServer && !dev) {
...
config.plugins.push(
new SWPrecacheWebpackPlugin({
filename: 'sw.js',
minify: false,
staticFileGlobsIgnorePatterns: [/\.next\//],
importScripts: ['/static/js/push-notifications.js'],
staticFileGlobs: [
'static/**/*' // Precache all static files by default
],
forceDelete: true,
runtimeCaching: [
// Example with different handlers
{
handler: 'fastest',
urlPattern: /[.](png|jpg|css)/
},
{
handler: 'networkFirst',
urlPattern: /^http.*/ // cache all files
}
]
}),
...
)
}
push-notifications.js
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');
const firebaseConfig = {...}
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
self.addEventListener('push', function(event) {
if (event.data) {
console.log('This push event has data: ', event.data.text());
} else {
console.log('This push event has no data.');
}
});
messaging.setBackgroundMessageHandler((payload) => {
let data = JSON.parse(payload.data.custom_notification);
let notificationTitle = data.title;
let notificationOptions = {
body: data.body,
icon: 'https://image.flaticon.com/icons/png/128/107/107822.png',
// options event
actions: [
{action: 'confirmAttendance', title: '? Confirm attendance'},
{action: 'cancel', title: '? Not coming'}
],
// For additional data to be sent to event listeners, needs to be set in this data {}
data: {confirm: data.confirm, decline: data.decline, open: data.open}
};
const promiseChain = clients
.matchAll({
type: 'window',
includeUncontrolled: true
})
.then(windowClients => {
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
windowClient.postMessage(payload);
}
})
.then(() => {
return self.registration.showNotification(notificationTitle, notificationOptions);
});
return promiseChain;
});
在_app.js中,我还将自定义组件用于注册服务工作者:
import { PureComponent } from 'react';
import 'firebase/messaging';
import localforage from 'localforage';
import initializedFirebaseApp from '../firebase.config';
class OfflineSupport extends PureComponent {
componentDidMount() {
if ('serviceWorker' in navigator) {
const messaging = initializedFirebaseApp.messaging();
navigator.serviceWorker
.register('sw.js')
.then((registration) => {
// Successfully registers service worker
messaging.useServiceWorker(registration);
})
.then(() => {
Notification.requestPermission().then((status) => {
console.log('Notification permission status:', status);
return messaging.getToken();
}).then((token) => {
localforage.setItem('FCM_TOKEN', token);
});
})
.catch((err) => console.error('Service worker error:' ,err));
}
}
componentWillUnmount () {
if ('serviceWorker' in navigator) {
initializedFirebaseApp.messaging().deleteToken().then((token) => localforage.removeItem('FCM_TOKEN', token));
}
}
render() {
return null;
}
}
export default OfflineSupport;
我收到带有“推送测试消息”选项的通知Firebase控制台。我也从push-notifications.js => eventListener('push')在console.log中获取数据。我的问题是,我想将数据从推送通知保存到redux,为此,我想访问它,但是push-notifications.js文件是服务工作者的设置文件,我无法导入到我的redux函数内部。谢谢!