4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

背景

Next.js で next-pwa を用いて PWA に対応させつつ、 ブラウザへ送ったプッシュ通知を受信して表示させる方法でちょっと詰まりました。というのも、next-pwa で自動生成されるサービスワーカーのスクリプトと、プッシュ通知を受信して表示させるためのサービスワーカーのスクリプトを共存させる方法が分からなかったためです。
next-pwaの GitHub に解決策が書かれていたので備忘録としてまとめておきます。

next-pwa を用いた PWA への対応

下記のような設定で、 next-pwa を利用します。

next.config.js
const withPWA = require('next-pwa')({ // next-pwa を読み込む
  dest: 'public',
  register: true,
  skipWaiting: true,
});
const withTM = require('next-transpile-modules')([
  'hogehoge',
  'fugafuga',
]);

const { i18n } = require('./next-i18next.config');

module.exports = withTM(
  withPWA({ // ここに記述
    reactStrictMode: true,
    i18n,
    images: {
      domains: [
        'somewhere',
        'localhost',
      ],
    },
    webpack: (config) => {
      config.module.rules.push({
        test: /\.svg$/,
        use: ['@svgr/webpack'],
      });
      return config;
    },
    async redirects() {
      return [
        {
          source: '/test/some',
          destination: '/',
          permanent: false,
        },
      ];
    },
    experimental: {
      scrollRestoration: true,
      optimizePackageImports: ['@mui/icons-material'],
      esmExternals: false,
    },
    eslint: {
      ignoreDuringBuilds: true,
    },
  }),
);

このように記述してビルドすると、public 配下に workbox-***.js というスクリプトと sw.js というサービスワーカーのスクリプトが自動生成されます。

プッシュ通知の受信

web-push を用いたプッシュ通知の送信方法については長くなるので割愛します。

下記のように、受信したプッシュ通知を表示させるために、
showNotification001.png

自分でサービスワーカーのスクリプトを書きます。

service-worker.js
// プッシュ通知(web-push)受信時の処理
self.addEventListener('push', function (event) {
  const data = event.data.json();
  const title = data.title || '新しいアクションがありました';
  const options = {
    body: data.body || '詳細はクリックして確認してください',
    icon: '/test-192x192.png',
    badge: '/test-192x192.png',
    data: {
      url: data.url,
    },
  };
  event.waitUntil(self.registration.showNotification(title, options));
});

// プッシュ通知(web-push)クリック時の処理
self.addEventListener('notificationclick', function (event) {
  event.notification.close();
  event.waitUntil(
    clients.matchAll({ type: 'window', includeUncontrolled: true }).then(() => {
      if (clients.openWindow) {
        return clients.openWindow(event.notification.data.url);
      }
    }),
  );
});

最初はこのスクリプトを public 配下に置いていましたが、同じスコープに2つのサービスワーカーが共存するような形になって上手くいきませんでした。
そのため、下記を参考にしました。

custom-worker を設置する

It demonstrates how to add custom worker code to the service worker generated by workbox.
(workbox が生成するサービスワーカーにカスタムワーカーコードを追加する方法を示します。)

結論、next.config.js がある階層に worker/index.js を作成し、先ほどの service-worker.js の中身をそこに書くだけでした。
これで PWA とプッシュ通知の表示を両立させることができ、無事に iOS で「ホーム画面に追加」したアプリにてプッシュ通知を受け取ることができました。
IMG_0120.PNG

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?