Search code examples
mongodbnext.jsnext-auth

Error when access the _id from mongodb nextjs auth when login and returning session user


I was following a tutorial to create a blogging site. I used Nextauth with Google and MongoDB to sign up. When a user is not signed in, I could sign up with Google and create a user in mongoDB. I can see the records in the database and each of them has _id, user, email..... I log in after the signup but when trying to get the _id from the mongoDB and assign it to the session user it fails.

The following statement is producing an error it says that _id is undefined

session.user.id = sessionUser._id.toString();

return session

This is the full block of code

import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';

import User from '@models/user';
import { connectToDB } from '@utils/database';

const handler = NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    })
  ],
  callbacks: {
    async session({ session }) {
      // store the user id from MongoDB to session
      const sessionUser = await User.findOne({ email: session.user.email });

      session.user.id = sessionUser._id.toString();

      return session;
    },
    async signIn({ account, profile, user, credentials }) {
      try {
        await connectToDB();

        // check if user already exists
        const userExists = await User.findOne({ email: profile.email });

        // if not, create a new document and save user in MongoDB
        if (!userExists) {
          await User.create({
            email: profile.email,
            username: profile.name.replace(" ", "").toLowerCase(),
            image: profile.picture,
          });
        }

        return true
      } catch (error) {
        console.log("Error checking if user exists: ", error.message);
        return false
      }
    },
  }
})

export { handler as GET, handler as POST }

Solution

  • it's because there is no user with such email in your database or the part

    User.findOne({ email: session.user.email })
    

    is somehow not doing what it is supposed to do I would recommend doing something like

    also check if email is the right field in your database there is a slight chance you might have mistyped it

    import NextAuth from 'next-auth';
    import GoogleProvider from 'next-auth/providers/google';
    
    import User from '@models/user';
    import { connectToDB } from '@utils/database';
    
    const handler = NextAuth({
        providers: [
            GoogleProvider({
                clientId: process.env.GOOGLE_ID,
                clientSecret: process.env.GOOGLE_CLIENT_SECRET,
            })
        ],
        callbacks: {
            async session({ session }) {
                // store the user id from MongoDB to session
                // log the email to make sure you have the right annotations since you are not using typescript | you may delete this in future
                console.log(session.user.email)
                const sessionUser = await User.findOne({ email: session.user.email });
                if (sessionUser) {
                    session.user.id = sessionUser._id.toString();
                    return session;                
                } else {
                    // no such user Handle it as your application needs
                }
    
            },
            async signIn({ account, profile, user, credentials }) {
                try {
                    await connectToDB();
    
                    // check if user already exists
                    const userExists = await User.findOne({ email: profile.email });
    
                    // if not, create a new document and save user in MongoDB
                    if (!userExists) {
                        await User.create({
                            email: profile.email,
                            username: profile.name.replace(" ", "").toLowerCase(),
                            image: profile.picture,
                        });
                    }
    
                    return true
                } catch (error) {
                    console.log("Error checking if user exists: ", error.message);
                    return false
                }
            },
        }
    })
    
    export { handler as GET, handler as POST }