如何将 PWA 与 Next.js 集成以允许通知和推送通知

How to integrate PWA with Next.js to allow for notifications and push notifications

我正在使用 next.js 构建 PWA,但遇到了一些问题。

我正在尝试将设备动​​作集成到我的用户帐户和地理位置,然后是通知。

基于此 repo,https://github.com/shadowwalker/next-pwa/ , and this tutorial, https://medium.com/@sarafathulla/how-to-add-firebase-push-notifications-in-next-js-react-8eecc56b5cab .

除了这些 API 之外,https://whatwebcando.today/device-motion.html and https://whatwebcando.today/geolocation.html .

目前 PWA 是使用 next-pwa 的样板,

next.config.js

module.exports = withPWA({
  pwa: {
    disable: process.env.NODE_ENV === 'development',
    dest: 'public',
    runtimeCaching,  
  },
  poweredByHeader: false,
},
withBundleAnalyzer(),

)

我很困惑如何将简单的设备动作集成到 PWA 中,以及如何继续前进。

如果有人能给我指出正确的方向,那就太好了!与通常的 Web 开发代码大不相同。

这对我有用

// public/firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/7.9.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.9.1/firebase-messaging.js');

firebase.initializeApp({
  apiKey: '****',
  authDomain: '*****',
  projectId: '*****',
  storageBucket: '******',
  messagingSenderId: '*****',
  appId: '*****',
  measurementId: '*****',
});

firebase.messaging();

//background notifications will be received here
firebase.messaging().setBackgroundMessageHandler((payload) => {
  const { title, body } = JSON.parse(payload.data.notification);
  var options = {
    body,
    icon: '/icons/launcher-icon-4x.png',
  };
  registration.showNotification(title, options);
});

// webpush.js
import 'firebase/messaging';
import firebase from 'firebase/app';
import localforage from 'localforage';

const firebaseCloudMessaging = {
  //checking whether token is available in indexed DB
  tokenInlocalforage: async () => {
    return localforage.getItem('fcm_token');
  },

  //initializing firebase app
  init: async function () {
    if (!firebase.apps.length) {
      firebase.initializeApp({
        apiKey: '****',
        authDomain: '*****',
        projectId: '*******',
        storageBucket: '******',
        messagingSenderId: '******',
        appId: '*****',
        measurementId: '*******',
      });

      try {
        const messaging = firebase.messaging();
        const tokenInLocalForage = await this.tokenInlocalforage();

        //if FCM token is already there just return the token
        if (tokenInLocalForage !== null) {
          return tokenInLocalForage;
        }

        //requesting notification permission from browser
        const status = await Notification.requestPermission();
        if (status && status === 'granted') {
          //getting token from FCM
          const fcm_token = await messaging.getToken();
          if (fcm_token) {
            //setting FCM token in indexed db using localforage
            localforage.setItem('fcm_token', fcm_token);
            //return the FCM token after saving it
            return fcm_token;
          }
        }
      } catch (error) {
        console.error(error);
        return null;
      }
    }
  },
};
export { firebaseCloudMessaging };

// _app.js
import { firebaseCloudMessaging } from '../webPush';
import firebase from 'firebase/app';

useEffect(() => {
    setToken();
    async function setToken() {
      try {
        const token = await firebaseCloudMessaging.init();
        if (token) {
          getMessage();
        }
      } catch (error) {
        console.log(error);
      }
    }
    function getMessage() {
      const messaging = firebase.messaging();
      console.log({ messaging });
      messaging.onMessage((message) => {
        const { title, body } = JSON.parse(message.data.notification);
        var options = {
          body,
        };
        self.registration.showNotification(title, options);
      });
    }
  });