Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

356
Views
Firebase does not authenticate when using next auth

I'm using next-auth with firebase adapter. Everything is working fine in terms of saving users in database, but something is not working in terms of authentication.

import NextAuth from "next-auth"

import GoogleProvider from "next-auth/providers/google"
import { FirebaseAdapter } from "@next-auth/firebase-adapter"

import { db } from "../../../utils/firebase/firebase"
import * as firestoreFunctions from 'firebase/firestore'

import { adminAuth } from "../../../utils/firebase/firebaseAdmin"

import { getAuth, signInWithCustomToken } from "firebase/auth"

const auth = getAuth()

export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
      state: false,
    }),
  ],
  adapter: FirebaseAdapter({
    db: db,
    ...firestoreFunctions,
  }),
  callbacks: {
    async signIn({ user, account, profile, email, credentials }) {
      console.log(user, 'user')
      const customToken = await adminAuth.createCustomToken(user.id)
      const customSignIn = await signInWithCustomToken(auth, customToken)
      console.log(customSignIn, 'customSignIn')
      console.log(customSignIn.user, 'customSignIn.user')
      user = customSignIn.user
      console.log(user, 'user 2')
      return true
    },
    async redirect({ url, baseUrl }) {
      return baseUrl
    },
    async session({ session, user, token }) {
      if (session?.user) {
        session.user.id = token.sub
      }
      return session
    },
    async jwt({ token, user, account, profile, isNewUser }) {
      if (isNewUser) {
        const additionalClaims = {
          isStudent: true,
          isTeacher: false,
          isStaff: false,
          isAdmin: false
        }
        const customToken = await adminAuth.createCustomToken(token.sub, additionalClaims)
        const customSignIn = await signInWithCustomToken(auth, customToken)
        user = customSignIn.user

      }
      return token
    }

  },

  session: {
    strategy: 'jwt',
  },
})

My users can log in, but are not authenticated.

const auth = getAuth()

onAuthStateChanged(auth, (user) => {
  if (user) {
    // User is signed in, see docs for a list of available properties
    // https://firebase.google.com/docs/reference/js/firebase.User
    console.log('user')
    console.log(user)
    // ...
  } else {
    console.log('no user')
    // User is signed out
    // ...
  }
})

The Observer returns 'no user', but I'm logged in.

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

You're not seeing a logged in user because the firebase auth is being done on the server side, and not the client side.

You should try passing the customToken to the session, then use it on the client side to sign in the user to firebase auth.

You would also want to wrap the useSession hook in a custom hook like below and use that instead of useSession.

const useFirebaseSession = () => {
  const session = useSession();
  const [status, setStatus] = useState(session.status);

  useEffect(() => {
    if (session && session.status === 'authenticated') {
      signInWithCustomToken(auth, session.customToken).then(() => {
        setStatus('authenticated');
      });
    }
  }, [session]);

  useEffect(() => {
    if(session.status !== 'authenticated') {
      setStatus(session.status)
    }
  }, [session.status]);

  return { data: session.data, status };
}
about 4 years ago · Juan Pablo Isaza Report

0

Ok, so what I finally did is: as @esi're said, pass the customToken created with firebase auth, to the session:

async jwt({
  token,
  user,
  account,
  profile,
  isNewUser
}) {
  if (isNewUser || user) {
    const additionalClaims = {
      isStudent: true,
      isTeacher: false,
      isStaff: false,
      isAdmin: false
    }
    const customToken = await adminAuth.createCustomToken(token.sub, additionalClaims)
    console.log(customToken, '***customToken')
    token.customToken = customToken
  }
  return token
}

Then, in the session callback:

async session({
  session,
  token,
  user
}) {
  if (session ? .user) {
    session.user.id = token.sub
    session.customToken = token.customToken
  }
  return session
},

And finally, in the page where users are first redirected:

  const [user, setUser] = useState()

  useEffect(() => {

    if (status === "authenticated") {
      const loggedInUser = {
        userName: session.user.name,
        userEmail: session.user.email,
        userPhoto: session.user.image,
        userUID: session.user.id,
      }

      signInWithCustomToken(auth, session.customToken)


      dispatch(setActiveUser(loggedInUser))

    }
  }, [status])

  const handleLogOut = () => {
    dispatch(setUserLogOutState())
    logout()
    signOut({
      callbackUrl: '/'
    }) //TODO: goodbye page
  
  
  // Rest of jsx code when session is true

And that's it. Hope it works for someone else too.

Thanks !

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!