🫠

Next.js × Rails API × Pusher でリアルタイム通知を実装する

2025/02/18に公開

Next.js × Rails API × Pusher でリアルタイム通知を実装する

今回は Next.js(フロントエンド)と Rails API(バックエンド)を使って、リアルタイム通知を Pusher で実装する方法について書いていこうと思います。

🎯 なぜ Pusher なのか?

リアルタイム通知を実装する手段はいくつかありますが、Pusher は以下の理由で採用しました。

  • 簡単に導入できる: WebSocket の実装を自前でやると結構面倒ですが、Pusher を使えばシンプルに実装可能。
  • 無料枠がある: 個人開発で試す分には十分。
  • Next.js との相性が良い: Pusher の JavaScript SDK を使えば、クライアント側も簡単にリアルタイム更新ができる。

それでは、実装を見ていきましょう!


🚀 Pusher のセットアップ

まずは Pusher のアカウントを作成し、アプリを作成します。

  1. Pusher にアクセスし、アカウントを作成。
  2. Channels のアプリを新規作成。
  3. ダッシュボードに表示される app_id, key, secret, cluster をメモ。

次に、Rails API で Pusher を使えるようにセットアップします。

📌 Rails 側の設定

# Gemfile

gem 'pusher'
$ bundle install

環境変数を .env に設定(dotenv を使う場合)

PUSHER_APP_ID=your_app_id
PUSHER_KEY=your_key
PUSHER_SECRET=your_secret
PUSHER_CLUSTER=your_cluster

Pusher を初期化する設定を config/initializers/pusher.rb に追加。

require 'pusher'

Pusher.app_id = ENV['PUSHER_APP_ID']
Pusher.key = ENV['PUSHER_KEY']
Pusher.secret = ENV['PUSHER_SECRET']
Pusher.cluster = ENV['PUSHER_CLUSTER']
Pusher.logger = Rails.logger
Pusher.encrypted = true

🔔 通知を送るメソッドを実装

class NotificationService
  def self.notify(channel_name)

    Pusher.trigger(channel_name, 'new_notification', {
      message: "新しいメッセージがあります"
    })
  rescue StandardError => e
    Rails.logger.error "Pusher trigger failed: #{e.message}"
  end
end

ポイント:

  • ユーザーごとに異なる channel_name を設定。
  • notification のデータを JSON に変換して送信。
  • 例外処理を追加してエラー時にログ出力。

これでバックエンド側の準備は OK です!


🎨 Next.js 側の実装

Pusher の JavaScript SDK をインストールします。(yarnを使った例)

$ yarn add pusher-js

Pusher を初期化して、通知を受け取るロジックを実装します。

import { useEffect, useState } from 'react';
import Pusher from 'pusher-js';

const pusher = new Pusher(process.env.NEXT_PUBLIC_PUSHER_KEY!, {
  cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER!,
});

const NotificationComponent = () => {
  const [notifications, setNotifications] = useState([]);
  const [unreadCount, setUnreadCount] = useState(0);

  useEffect(() => {
    const channel = pusher.subscribe('hoge');

    channel.bind('new_notification', (data) => {
      setNotifications((prev) => [data.notification, ...prev]);
      setUnreadCount((prev) => prev + 1);
    });

    return () => {
      channel.unbind_all();
      channel.unsubscribe();
    };
  }, []);

  return (
    <div>
      <h3>通知 ({unreadCount})</h3>
      <ul>
        {notifications.map((notif, index) => (
          <li key={index}>{notif.message}</li>
        ))}
      </ul>
    </div>
  );
};

export default NotificationComponent;

ポイント:

  • useEffect を使って Pusher のチャンネルを購読。
  • bind('new_notification', callback) でリアルタイム通知を受け取る。
  • 通知を state に追加し、未読カウントを更新。
  • useEffect のクリーンアップでチャンネルを解除。

🎥 実際の動き

quitta.gif
左側の画面でレビューに「いいね」すると、リアルタイムで右側の画面の通知アイコンに「1」という数字が増えています。これは、Pusher を利用して、Rails 側で通知を発行し、Next.js 側で購読・即時反映しているためです。🔔✨

🎬 まとめ

これで、Next.js × Rails API × Pusher を使ってリアルタイム通知を実装できました!

✅ Rails 側で Pusher をセットアップし、通知を送信。
✅ Next.js 側で Pusher を購読し、リアルタイム更新。
✅ クリーンアップ処理も忘れずに実装。

個人開発でも活躍する Pusher、ぜひ使ってみてください!🚀

Discussion