next.jsgoogle-cloud-firestorenext-auth

How to store user info on firestore using adapter with next-auth v4+?


How can we store user info on firestore automatically when user sign up. Looking for built in method like adapters in next-auth to avoid mistakes in storing info efficiently. Doc tutorials uses prisma and mongo as example but I am looking for storing it on firestore.

There is canary version of firebase adapter with next-auth v5 beta. But it throws error as I'm using latest firebase in my project already. Apart from version issue there is error like r is not function... when i use v5 beta (5.0.0-beta.25) similar question for this error

doc ref https://authjs.dev/getting-started/adapters/firebase

By the way the firebase adapter uses firebase sdk which is client sdk. So this way we are using client sdk on server side in nextjs. I wonder how they are using firebase client sdk on server side of nextjs.


Solution

  • Here is simple way to do so.

    Step 1 : create config file and initialize firebase admin app to use firestore instance
    Step 2 : create route js and pass firestore instance to firestore adapter in auth options. that's it!

    Initialize NextAuth.js with a Route Handler. Here I am taking two providers Google and Github with firestore adapter to store user info.

    Step 1 (You can ignore and use your own existing config to get firestore instance )
    Initialize firebase-admin app and export the instance of firestore (or follow your own way to initialize and use firestore instance directly in route.js).

    import { PROJECT_ID } from '../firebase/constants/project';
    import serviceAccount from './secrets/ServiceAccount77.json';
    
    import admin from 'firebase-admin';
    import { getApps } from 'firebase-admin/app';
    import { getFirestore } from 'firebase-admin/firestore';
    
    
    if (!getApps().length) {
    
      admin.initializeApp({
        credential: admin.credential.cert(serviceAccount),
        projectId: PROJECT_ID,
        storageBucket: `${PROJECT_ID}.appspot.com`,
      });
    
    }
    
    const db = getFirestore();
    
    export { admin, db };
    

    Step 2 :
    api/auth/[...nextauth]/route.js

    import NextAuth from "next-auth"
    import GithubProvider from "next-auth/providers/github"
    import GoogleProvider from "next-auth/providers/google"
    import { FirestoreAdapter } from "@auth/firebase-adapter"
    import { db } from '@/lib/firebase/config';
    
    export const authOptions = {
      adapter: FirestoreAdapter(db),
      providers: [
        GoogleProvider({
          clientId: process.env.GOOGLE_ID,
          clientSecret: process.env.GOOGLE_SECRET,
        }),
        GithubProvider({
          clientId: process.env.GITHUB_ID,
          clientSecret: process.env.GITHUB_SECRET,
        }),
        // ...add more providers here
      ],
    }
    
    const handler = NextAuth(authOptions)
    export { handler as GET, handler as POST }
    

    This is basic setup creates user related info on firestore. Current version and configs creates collections as sessions, accounts and users. See screenshots

    Result

    collection - account

    screenshot of firestore collection - accounts

    collection - sessions

    screenshot of firestore collection - sessions

    collection - user

    screenshot of firestore collection - users

    Version i used while trying it

    "firebase-admin": "^12.7.0",
    "next": "^14.2.5",
    "next-auth": "^4.24.10",
    "react": "^18.3.1",
    "@auth/firebase-adapter": "^2.7.3",