databasemongodbnext.jscaching

Data Not Updating on Dashboard in Production Environment


I have a web application with payment system integration, and I am facing an issue where the payment data is not updating in the dashboard in the production environment, although it works fine in development.

see diagramme: https://excalidraw.com/#json=uwcITb3OzG_H2KBvCcWSJ,-Epm-_UIdZgrTsVRfJQ2nA

if you dont want to see diagramme:

Client:

PayPage: Handles the payment process. Dashboard: Displays the payment data, which includes Status, Exam, Full Name, and Email. Server:

Webhook: Receives payment data from the payment provider. API: Fetches payment data from the database. Database:

Stores payment data.

Flow:

PayPage: User completes a payment. Webhook: Receives payment data and updates the database. Dashboard: Fetches payment data from the API and displays it.

Problem:

Development: Data is saved in the database and updates correctly on the dashboard.

Test with Postman at Development mode

Production: Data is saved in the database, but it does not update on the dashboard.

Test with Postman at Production mode


import { getUsersPaymentsData } from "./FetchUsersPaymentsData";
import { currentUser } from "@clerk/nextjs/server";

export default async function UsersInfo() {
  try {
    // get data of user
    const data = await getUsersPaymentsData();

    // get data of this current user from clerk
    const user = await currentUser();

    if (!user) {
      return (
        <div className="border-t-2 sm:border-t-0 sm:border-l-2 border-accent pt-4 sm:pt-0 sm:pl-4">
          <p className="text-navy-900">Status: User not found</p>
          <p className="text-navy-900">Exam: N/A</p>
          <p className="text-navy-900">FullName: N/A</p>
          <p className="text-navy-900">Email: N/A</p>
        </div>
      );
    }

    // get specific data from clerk
    const serializedUser = {
      id: user.id,
      fullName: user.fullName,
      primaryEmailAddress: user.primaryEmailAddress?.emailAddress,
    };

    // check if the current user have data on db by userid
    const userStatusPayments = data.payments.find(
      (payment) => payment.clerkUser?.userID === serializedUser.id
    );

    // console.log(userStatusPayments.id);

    // if user not found at db return this
    if (!userStatusPayments) {
      return (
        <div className="border-t-2 sm:border-t-0 sm:border-l-2 border-accent pt-4 sm:pt-0 sm:pl-4">
          <p className="text-navy-900">Status: FREE</p>
          <p className="text-navy-900">Exam: No Specified</p>
          <p className="text-navy-900">FullName: {serializedUser.fullName}</p>
          <p className="text-navy-900">
            Email: {serializedUser.primaryEmailAddress}
          </p>
        </div>
      );
    }

    // if everything is good and the user is found return his data and show it
    return (
      <div className="border-t-2 sm:border-t-0 sm:border-l-2 border-accent pt-4 sm:pt-0 sm:pl-4">
        <p className="text-navy-900">
          Status: {userStatusPayments.lemonsqueezyUser.paymentsInfo.status}
        </p>
        <p className="text-navy-900">Exam: {userStatusPayments.examName}</p>
        <p className="text-navy-900">
          FullName: {userStatusPayments.clerkUser.userFullName}
        </p>
        <p className="text-navy-900">
          Email: {userStatusPayments.clerkUser.userEmail}
        </p>
      </div>
    );

  // that for catch error and return it
  } catch (error) {
    console.log("Error loading user payment info: ", error);
    return (
      <div className="border-t-2 sm:border-t-0 sm:border-l-2 border-accent pt-4 sm:pt-0 sm:pl-4">
        <p className="text-navy-900">Status: Error loading data</p>
      </div>
    );
  }
}


import config from "@/config";

export const getUsersPaymentsData = async () => {
  try {
    const res = await fetch(`${config.domainNameProduction}/api/payments`, {
      cache: "no-store",
    });

    if (!res.ok) {
      throw new Error("Failed to fetch topics");
    }

    return res.json();
  } catch (error) {
    console.log("Error loading topics: ", error);
  }
};


this api/payments/route.js


import clientPromise from "@/utils/mongodb";
import { NextResponse } from "next/server";

export async function GET() {
  try {
    const client = await clientPromise;
    const db = client.db(process.env.MONGODB_DB);

    const payments = await db.collection("payments").find({}).toArray();

    return NextResponse.json({ payments }, { status: 200 });
  } catch (error) {
    console.log(error);
    return NextResponse.json({ message: "Error", error }, { status: 500 });
  }
}

I search and I found, when I went to Data Cache > Purge Cache > Purge Everything and remove it the data on app is updated and show it on dashboard. But its not for long time. anther way, You must do this for every update that occurs relative to the DataBase


Solution

  • I changed my way of thinking by starting to program a function from scratch, i finding mistakes I had made, and then fixing them.

    This is new code:

    import { getUsersPaymentsData } from "./FetchUsersPaymentsData";
    import { currentUser } from "@clerk/nextjs/server";
    
    export default async function UsersInfo({ params }) {
      const { id } = params;
      // console.log("Received ID: ", id); // Output: it's working, ID is received
    
      const ClerkUser = await currentUser();
    
      const serializedUser = {
        id: ClerkUser.id,
        fullName: ClerkUser.fullName,
        primaryEmailAddress: ClerkUser.primaryEmailAddress?.emailAddress,
      };
    
      const userData = await getUsersPaymentsData(id);
      // console.log("Fetched User Data:", userData); // Output: undefined or actual data
    
      if (!userData || !userData.foundPayments) {
        return (
          <div className="border-t-2 sm:border-t-0 sm:border-l-2 border-accent pt-4 sm:pt-0 sm:pl-4">
            <p className="text-navy-900">Status: FREE</p>
            <p className="text-navy-900">Exam: No Specified</p>
            <p className="text-navy-900">FullName: {serializedUser.fullName}</p>
            <p className="text-navy-900">Email: {serializedUser.primaryEmailAddress}</p>
          </div>
        );
      }
    
      const user = userData.foundPayments;
      // console.log("Found Payments: ", user); // For debugging
    
      return (
        <div className="border-t-2 sm:border-t-0 sm:border-l-2 border-accent pt-4 sm:pt-0 sm:pl-4">
          <p className="text-navy-900">
            Status: {user.lemonsqueezyUser.paymentsInfo.status}
          </p>
          <p className="text-navy-900">Exam: {user.examName}</p>
          <p className="text-navy-900">FullName: {user.clerkUser.userFullName}</p>
          <p className="text-navy-900">
            Email: {user.lemonsqueezyUser.customerEmail}
          </p>
        </div>
      );
    }
    
    import config from "@/config";
    
    export async function getUsersPaymentsData(id) {
      try {
        const res = await fetch(
          `${config.domainNameProduction}/en/api/payments/${id}`,
          {
            cache: "no-store",
          }
        );
    
        if (!res.ok) {
          throw new Error("Failed to fetch payments data");
        }
    
        const data = await res.json(); // Await the response
        return data;
      } catch (error) {
        console.error("Error fetching payment data:", error); // Improved error logging
        return null; // Return null in case of error
      }
    }
    
    

    inside my api

    // api/payments/route.js

    import Payments from "@/models/Payments";
    import { NextResponse } from "next/server";
    
    export async function GET() {
      try {
        const payments = await Payments.find();
        return NextResponse.json({ payments }, { status: 200 });
      } catch (error) {
        console.log(error);
        return NextResponse.json({ message: "Error", error }, { status: 500 });
      }
    }
    
    

    // api/payments/[id]/route.js

    // import Payments from "@/models/Payments";
    import { NextResponse } from "next/server";
    import clientPromise from "@/utils/mongodb";
    
    export async function GET(req, { params }) {
      const { id } = params;
    
      try {
        const client = await clientPromise; // Ensure MongoDB connection is established
        const db = client.db();
    
        const foundPayments = await db.collection('payments').findOne({ "clerkUser.userID": id });
    
        if (!foundPayments) {
          return NextResponse.json(
            { message: "Error: Payments Information Not Found" },
            { status: 404 }
          );
        }
    
        return NextResponse.json({ foundPayments }, { status: 200 });
      } catch (error) {
        console.error("Error fetching payment data:", error); // Improved error logging
        return NextResponse.json(
          { message: "Server Error", error: error.message },
          { status: 500 }
        );
      }
    }