roee
roee

Reputation: 107

cannot connect to mongoDB from middleware.js (NextJS). (WEBPACK Error)

I have created a NextJS application and I want to use mongoDB as my database, but I have a problem, when ever I'm calling the function that uses the database from one of the pages it works just fine, but when I am calling it from the middleware.js that clerk is using I am getting this error:

mongoose__WEBPACK_IMPORTED_MODULE_0___default(...).connect is not a function

The nextjs version I am using is 14.0.4 and the mongoose is 8.0.3. And the package I installed is mongoose using the npm install mongoose command.

I am using the connect statment in the user model.

/lib/models/user.model.js contains this code:

"use server";

import mongoose, { Schema } from "mongoose";

mongoose.connect(process.env.MONGODB_URI);
mongoose.Promise = global.Promise;

const userSchema = new Schema(
  {
    // some fields here
  },
  { timestamps: true }
);

const User = mongoose.models.User || mongoose.model("User", userSchema);

export default User;

these are the functions that I am calling from different parts of the code that contains the functions /lib/actions/actions.js:

"use server";

import User from "../models/user.model";

export async function updateUser(params) {
  try {
    await User.findOneAndUpdate(
      {
        // putting the params here.
      }
      { upsert: true }
    );
  } catch (error) {
    throw new Error(`Faild to create/update user ${error.message}`);
  }
}

export async function fetchUser(ClerkUserId) {
  try {
    const user = await User.findOne({ ClerkUserId });
    return user;
  } catch (error) {
    console.error("Error fetching user:", error);
    return null;
  }
}

when I call the updateUser from /components/forms/OnBoardingForm.jsx the process works greate and the data is being inserted/updated to the database. (The form is called from a page.jsx that is int eh app route).

but when I am calling is from the middleware that is in /middleware.js that is running before the pages of the app I am getting the error mentioned above.

Does someone knows why it is happening and how can I fix it?

For thos who who wants to get a look on the OnBoardingForm.jsx, middleware.js and layout.js:

OnBoardingForm.jsx:

"use client";

import { useState } from "react";
import { updateUser } from "@/lib/actions/actions";

const OnBoardingForm = ({ userData }) => {
  const [username, setUsername] = useState(userData.username);
  const [phoneNumber, setPhoneNumber] = useState("");
  const [location, setLocation] = useState("");

  const submitForm = async () => {
    await updateUser(
      userData.id,
      userData.username,
      userData.firstName,
      userData.lastName,
      userData.location,
      userData.phoneNumber
    );
  };

  return (
    <>
      <div className="flex flex-col px-20 gap-6 mt-20">
        <div className="flex flex-col">
          <label>username</label>
          <input
            className="px-5 py-2 rounded text-black"
            value={username}
            placeholder="Enter your busines name"
            onChange={(e) => {
              userData.username = e.target.value;
              setUsername(e.target.value);
            }}
          />
        </div>
        <div className="flex flex-col">
          <label>location</label>
          <input
            className="px-5 py-2 rounded text-black"
            value={location}
            placeholder="Enter your location"
            onChange={(e) => {
              userData.location = e.target.value;
              setLocation(e.target.value);
            }}
          />
        </div>
        <div className="flex flex-col">
          <label>phone number</label>
          <input
            className="px-5 py-2 rounded text-black"
            value={phoneNumber}
            placeholder="Enter your phone number"
            onChange={(e) => {
              userData.phoneNumber = e.target.value;
              setPhoneNumber(e.target.value);
            }}
          />
        </div>
        <button
          className="mt-5 bg-white rounded py-3 font-bold"
          style={{
            fontSize: "1.2rem",
            backgroundColor: "#6a48f2",
          }}
          onClick={() => {
            submitForm();
          }}
        >
          Continue
        </button>
      </div>
    </>
  );
};

export default OnBoardingForm;

middleware.js

"use server";

import { authMiddleware, redirectToSignIn } from "@clerk/nextjs";
import { fetchUser } from "./lib/actions/actions";

export default authMiddleware({
  publicRoutes: ["/"],
  afterAuth: async (auth, req, evt) => {
    if (!auth.userId && !auth.isPublicRoute) {
      return redirectToSignIn({ returnBackUrl: req.url });
    } else if (auth.userId) {
      await fetchUser(auth.userId);
    }
  },
});

export const config = {
  matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"],
};

layout.js

import { Inter } from "next/font/google";
import "./globals.css";
import { ClerkProvider } from "@clerk/nextjs";

const inter = Inter({ subsets: ["latin"] });

export const metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({ children }) {
  return (
    <ClerkProvider>
      <html lang="en">
        <body className={inter.className}>
          <main className="flex flex-col w-full min-h-screen">{children}</main>
        </body>
      </html>
    </ClerkProvider>
  );
}

Upvotes: 1

Views: 204

Answers (1)

Unclebigbay
Unclebigbay

Reputation: 103

Currently mongodb calls are not supported in Next.js middleware because middleware edge runtime nature is not compatible with mongodb adapter for connection.

There are alternatives to approach this here: https://medium.com/@chxiuy/mongodb-in-nextjs-overcoming-the-edge-runtime-middleware-hurdle-4beee31eaa30 and an official discussion about it here: https://github.com/vercel/next.js/discussions/46722

Upvotes: 0

Related Questions