Next.js Discord

Discord Forum

How can displaying real-time advertisements to users in Next.js 14 with Pusher and MongoDB?

Unanswered
Northeast Congo Lion posted this in #help-forum
Open in Discord
Northeast Congo LionOP
I am trying to create a real-time advertisement queue for users in my Next.js 14 application, where each user sees one advertisement at a time, similar to Google Ads. I am using Pusher for real-time data delivery, but I am facing issues when integrating it with MongoDB.

What I expected: I expected the advertisement to be displayed in real-time to the user, with the next advertisement in the queue being displayed once the current one is dismissed.

I also tried with useEffect to fetch data at one time and then make queue but its not real time

below is the code for pusher and adbox component

Client Component:

import React, { useEffect, useState } from 'react';
import Pusher from 'pusher-js';
import Image from 'next/image';

type AdType = {
    _id: string;
    link: string;
    image: string;
}

const AdBox = () => {
  const [currentAd, setCurrentAd] = useState<AdType | null>(null);

  useEffect(() => {

     fetch('/api/advertisement/getAllAds').then(response => {
       console.log('Ad rotation triggered:', response);
     }).catch(error => {
    console.error('Error triggering ad rotation:', error);
     });

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

    const channel = pusher.subscribe('ad-channel');
    channel.bind('ad-update', function(data:any) {
      setCurrentAd(data.ad);
    });
    
    return () => {
      pusher.unsubscribe('ad-channel');
      channel.unbind_all();
    };
        
  }, []);
  
  return (
    <div>
      {currentAd && (
        <div>
          <Image src={currentAd.image} alt="Advertisement" width={300} height={300} layout="responsive" />
          <a href={currentAd.link} target="_blank" rel="noopener noreferrer">Visit Ad</a>
        </div>
      )}
    </div>
  );
};

export default AdBox;

1 Reply

Northeast Congo LionOP
serveless route file (getAllAds/route.tsx)

import {connectDB} from '@/lib/database/mongoose';
import Advertisement from '@/lib/database/models/advertisement.model';
import { NextResponse } from 'next/server';
import Pusher from 'pusher';

const pusher = new Pusher({
  appId: process.env.PUSHER_APP_ID!,
  key: process.env.PUSHER_KEY!,
  secret: process.env.PUSHER_SECRET!,
  cluster: process.env.PUSHER_CLUSTER!,
  useTLS: true
});

export default async function GET(req: Request) {
    try {
      await connectDB();
      const ads = await Advertisement.find({}); 

      console.log('ads in route pusher', process.env.PUSHER_APP_ID)


      let currentAdIndex = 0;
      setInterval(async () => {
        
        const ad = ads[currentAdIndex];
        console.log(`Sending ad: ${currentAdIndex}`, ad);
        await pusher.trigger('ad-channel', 'ad-update', {
          ad
        });
        currentAdIndex = (currentAdIndex + 1) % ads.length;
      }, 20000);

      NextResponse.json({ message: 'Ad rotation started' });
    } catch (error) {
      console.error('Error rotating ads:', error);
    }
  
}