-
Hi all, I have currently set up my next.js app use next-auth with the Firebase Adapter, and am using the GoogleProvider for login. export default NextAuth({
// Configure one or more authentication providers
// https://next-auth.js.org/providers
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_ID as string,
clientSecret: process.env.GOOGLE_SECRET as string,
}),
EmailProvider({
server: process.env.EMAIL_SERVER,
from: process.env.EMAIL_FROM,
}),
],
// see https://authjs.dev/reference/adapter/firebase#usage
// adapter: FirestoreAdapter({}),
adapter: FirestoreAdapter({
credential: cert({
projectId: process.env.FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_PRIVATE_KEY,
}),
}),
callbacks: {
async session({ session, token }) {
...
return session
},
},
session: {
strategy: 'jwt',
},
debug: process.env.NODE_ENV !== 'production',
}) At the same time, I am using the Firestore DB on Client ( const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
}
// Initialize Firebase
const app = initializeApp(firebaseConfig)
export const db = getFirestore(app)
export const auth = getAuth(app) I now ran into a problem when configuring the Firestore rules. As I access the DB client-side in my Next.js app, I need to limit access to documents by the user's ID, which I have set up with the rules config. I validated these rules to be correct for my use case using the tool provided within Firestore by Google. The problem: the authorisation of Firestore DB calls on Client using ( An example call: import { db } from '../../firebase/setup'
...
if (credits > n) {
await handleSetCredits(uid, credits - n)
return true
} At this stage of my investigation, I assume the following is the issue:
This leads to the Firebase Client not having a user session, and the Firestore access only works as long as all read & write is allowed. Does someone have an idea on how to go about solving this? How can I make Firebase use the next-auth user session when reading from Firestore on the client? Any ideas, hints or suggestions are appreciated! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
I was able to solve this, leaving the solution here in case anybody comes across the same situation: One approach to achieve this is to use a custom token generated by your Next.js server and use it to sign in the user client-side with Firebase. Here's a high-level overview:
Implementation:
npm install firebase-admin
import * as admin from 'firebase-admin'
if (!admin.apps.length) {
admin.initializeApp({
credential: admin.credential.cert({
projectId: process.env.FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_PRIVATE_KEY,
}),
})
}
callbacks: {
async session({ session, token }) {
// ...
if (token && token.uid) {
const firebaseToken = await admin.auth().createCustomToken(token.uid)
session.firebaseToken = firebaseToken
}
return session
},
},
import { getAuth, signInWithCustomToken } from 'firebase/auth'
const auth = getAuth(app)
async function syncFirebaseAuth(session) {
if (session && session.firebaseToken) {
try {
await signInWithCustomToken(auth, session.firebaseToken)
} catch (error) {
console.error('Error signing in with custom token:', error)
}
} else {
auth.signOut()
}
}
import { useSession } from 'next-auth/react'
function MyApp({ Component, pageProps }) {
const { session } = useSession()
useEffect(() => {
syncFirebaseAuth(session)
}, [session])
// ...
} Now the client-side Firebase instance is aware of the user's authentication state, allowing you to use Firestore rules based on the user's ID. |
Beta Was this translation helpful? Give feedback.
-
https://www.youtube.com/watch?v=OOUsvDOKlGs this video solves this issue in minute: 2:16:00 |
Beta Was this translation helpful? Give feedback.
-
@yvokeller One thing to notice here that this doesn't set the UID as identifier in firebase auth. It resolves to "-" for all users. Any workaround for that. |
Beta Was this translation helpful? Give feedback.
I was able to solve this, leaving the solution here in case anybody comes across the same situation:
One approach to achieve this is to use a custom token generated by your Next.js server and use it to sign in the user client-side with Firebase.
Here's a high-level overview:
Implementation: