Gives 502 error when i deployed to Netlify but works perfectly in local

I will go crazy if i keep getting the same error for one more day, as i’m literally stuck trying to fix that serverless function error on netlify ! It all works fine when running on development mode, but when i deploy on netlify and hitting the “signin” link on the navbar, it suddenly gives error as follows, im sure nothing is wrong with the logic both in frontend and backend. Asking netlify to increase timeout limit makes just no sense in my opinion because most users wont even wait for the page to load more than 4 seconds. All the other pages works perfectly and i cant really make sense of that, any help is wholeheartedly appreciated, thanks in advance ! i need to show the current part of the site to customer soon and im just stuck here…

there is almost nothing left i have not yet given a go…

production link: https://main--musical-lokum-78f90a.netlify.app/

one of the errors popping out so often as soon as i hit the “signin”:

.env file

MONGODB_URL=mongodb+srv://xxxxxx:xxxxxxxxxxxx@cluster0.9ksscei.mongodb.net/?retryWrites=true&w=majority
GOOGLE_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxxx

JWT_SECRET=aWRlYWNoYW1iZXJwbGFjZXdvb2RmaXNoaXRzYWRkd2l0aGRpcnR5aHVycnlyZWNlbnQ=
NEXTAUTH_SECRET=ZnVydGhlcmxhcmdlc3RkaXNjdXNzaW9udGhvdXNhbmRtYWlsbWluZXJhbHNmdWxscmU=

NEXTAUTH_URL=https://musical-lokum-78f90a.netlify.app
ACTIVATION_TOKEN_SECRET=1996021996
BASE_URL=https://musical-lokum-78f90a.netlify.app
MAILING_SERVICE_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
MAILING_SERVICE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxxxxxx
MAILING_SERVICE_CLIENT_REFRESH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SENDER_EMAIL=xxxxx@gmail.com
RESET_SECRET=1996021996



[…nextauth].js file

import NextAuth from 'next-auth'
import GoogleProvider from 'next-auth/providers/google'
import GithubProvider from 'next-auth/providers/github'
import CredentialsProvider from "next-auth/providers/credentials";
import dotenv from 'dotenv'
import User from '../../../models/User'
import bcrypt from 'bcrypt'
import joi from 'joi'
import {connectDB, disconnect} from '../../../utils/db'
import {MongoDBAdapter} from '@next-auth/mongodb-adapter'
import clientPromise from './lib/mongodb'

import { getToken } from 'next-auth/jwt'


dotenv.config()


 const loginSchema = joi.object({
  email: joi.string().email().required(),
  password: joi.string().min(6).required(),

});



export default NextAuth({
     adapter : MongoDBAdapter(clientPromise),
  providers: [
    CredentialsProvider({
      id: 'credentials',
     name : 'Sign in',
      credentials : {
        email: { label: "Username", type: "text", placeholder: "jsmith" },
        password: { label: "Password", type: "password", placeholder: "********" }
      },

      async authorize(credentials,req) {

        try {

         await connectDB()

        const email = credentials.email
        const password = credentials.password
        console.log(email,password)

        if (!email || !password) {
          
          throw new Error('Please provide an email and password.');
        }

        const {error} = loginSchema.validate({email,password})
        if (error) {
          await disconnect()
          throw new Error(error.details[0].message);
        }

        const user = await User.findOne({email})

        if (!user) {
          await disconnect()
          throw new Error('Invalid email or password.');
        }

        const checkMatch = await bcrypt.compare(password, user.password)

        if (!checkMatch) {
          await disconnect()
          throw new Error('Invalid email or password.');
        }




        return user
      } catch (error) {
        await disconnect()
        throw new Error(error.message);

      }

    
      }
      
      }),
 
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret:process.env.GOOGLE_CLIENT_SECRET,

    }),
    GithubProvider({
      clientId: "Iv1.2a94b24ea5010c98",
      clientSecret: "71ff167e340484f06b9e03ff73bb64e4e667f8cb",
    }),
    
  
  ],

  pages: {
    signIn: '/signin',
  },

  callbacks: {
    async session({session, token}) {
    
      
      let user = await User.findById(token.sub);
     
      session.user.id = token.sub || user?._id?.toString();
      session.user.role = user?.role || 'user';      
      return session;
    }
  },

 

    session: {
     
    strategy: 'jwt',


    },
    jwt: {
      secret: process.env.JWT_SECRET,

    },
    secret: process.env.NEXTAUTH_SECRET,




})

signin.js page (frontend)

import React from "react";

import styles from "../styles/signin.module.scss";
import { BiLeftArrowAlt } from "react-icons/bi";
import Link from "next/link";

import LoginInput from "../components/custom/loginIput";
import Image from "next/image";
import { signIn } from "next-auth/react";
import { useState } from "react";

import { getProviders } from "next-auth/react";

import { useRouter } from "next/router";
import { getSession } from "next-auth/react";
import BarLoader from "react-spinners/BarLoader";
import {getCsrfToken} from 'next-auth/react'


function Signin({ providers, csrfToken, callbackUrl }) {
  const [user, setUser] = useState({
    email: "",
    password: "",
  });

  const router = useRouter();

  const [message, setMessage] = useState({
    error: "",
    successMessage: "",
  });

  const [loading, setLoading] = useState(false);
  
 

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    const result = await signIn("credentials", {
      redirect: false,
      email: user.email,
      password: user.password,
    });

    if (result?.error) {
      setLoading(false);
      setMessage({ ...message, error: result.error });
    }

    if (result?.ok) {
      const session = await getSession();
      console.log(session);
      const successMessage = "You have successfully logged in !";
      const waitTime = 3000;
      setLoading(false);

      setMessage({ ...message, successMessage });

      let timer = setTimeout(() => {
        router.push(callbackUrl || "/");
      }, waitTime);

      return () => {
        clearTimeout(timer);
      };
    }
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setUser({ ...user, [name]: value });
   
  };

  return (
    <>
     

      <div className={styles.login}>
        <div className={styles.login__container}>
          <div className={styles.login__header}>
            <div className={styles.goback__svg}>
              <BiLeftArrowAlt />
            </div>

            <span>Shop over +1 million products !</span>
          </div>

          <div className={styles.login__form}>
            <Image src="/profilelogo.svg" width={100} height={100} alt="not" />
            <h3>Sign in</h3>
            <p> Sign in and start shopping immediately !</p>

            <form onSubmit={handleSubmit}>
              <LoginInput
                icon="user"
                placeholder="Username"
                onChange={handleChange}
                type="text"
                name="email"
                value={user.email}
                required={true}
              />
              <LoginInput
                icon="password"
                placeholder="Password"
                onChange={handleChange}
                type="password"
                name="password"
                value={user.password}
                required={true}
              />
              {message.error && (
                <div
                  className={styles.login__error}
                  onAnimationEnd={() => setMessage({ ...message, error: "" })}
                  key={message.error}
                >
                  <p>{message.error}</p>
                </div>
              )}

              {message.successMessage && (
                <div
                  className={styles.login__success}
                  onAnimationEnd={() =>
                    setMessage({ ...message, successMessage: "" })
                  }
                  key={message.successMessage}
                >
                  <p>{message.successMessage}</p>
                </div>
              )}

              <div className={styles.links}>
                <span>
                  <Link className={styles.links__span__a} href="/signup">
                    Create an account
                  </Link>
                </span>
                <span>
                  <Link
                    className={styles.links__span__a}
                    href="auth/forgot"
                  >
                    Forgot password
                  </Link>
                </span>
              </div>

              <button className={styles.loginButton} type="submit">
                {
                  loading ? <BarLoader
                  color="#fff"
                  height={5}
                  loading = {loading}
                  speedMultiplier={2}
                  width={100}
                />
                : "Sign in"
                }

              </button>

              <div className={styles.divider}>
                <span>or</span>
              </div>
              { providers &&
                Object.values(providers).map((item, index) =>
                item.id === "credentials" ? null : (
                  <div className={styles.login__social} key={index}>
                    <a onClick={() => signIn(item.id)}>
                      <Image
                        src={`/${item.id}.svg`}
                        width={20}
                        height={20}
                        alt={`${item.name}`}
                      />
                      <span>Continue with {`${item.name}`}</span>
                    </a>
                  </div>
                )
              )}
            </form>
          </div>
        </div>
      </div>

    </>
  );
}

export default Signin;

export async function getServerSideProps(context) {
  const { req, query } = context;
  const providers = await getProviders();

  const session = await getSession({ req });

  const csrfToken = await getCsrfToken(context);
  const { callbackUrl } = query;

  let defaultCallbackUrl = "/";

  if (callbackUrl) {
    defaultCallbackUrl = callbackUrl;
  }

  if (session) {
    return {
      redirect: {
        destination: defaultCallbackUrl,
      },
    };
  }

  return {
    props: { providers, session, csrfToken, callbackUrl: defaultCallbackUrl },
  };
}


mongodb.js (next auth adapter)


import { MongoClient } from "mongodb";

const uri = process.env.MONGODB_URL;
const options = {
  useUnifiedTopology: true,
  useNewUrlParser: true,
};

let client;
let clientPromise;

if (!process.env.MONGODB_URL) {
  throw new Error("Please add your Mongo URI to .env.local");
}

if (process.env.NODE_ENV === "development") {
 
  if (!global._mongoClientPromise) {
    client = new MongoClient(uri, options);
    global._mongoClientPromise = client.connect();
  }
  clientPromise = global._mongoClientPromise;
} else {

  client = new MongoClient(uri, options);
  clientPromise = client.connect();
  
}

export default clientPromise;

1 Like

still waiting for urgent helps !!!

I have the same issue, see my post.

@igorsavinkin your issue is not the same—your function crashes because of a missing library file while the issue with @Abdulberk’s function is it is not finishing within the 10 second execution limit.

@jasiqli , thanks for the explanation. Сould you direct me to the resources of fixing " missing library file" ?

Hey, i got the exact same issue. I tried deploying to Netlify, tried everything, from changing how the env variables are used, adding them to next config, following the steps suggested in here https://github.com/nextauthjs/next-auth/issues/1021 and even tried on Vercel, but without success. The issue is always the same, a 502 when trying to login. Did you had any success in the meanwhile?