Open GroophyLifefor opened 8 months ago
Don't use NextAuth on App router. Atleast that is what i came to conclusion via my experience.
Don't use NextAuth on App router. Atleast that is what i came to conclusion via my experience.
Is it fixing when I just don't use App Router? Really?
Not even a return for how many days, great team, excellent project, The last praises I said is not serious.
next-auth
has 250 active issues and nearly 90 pr's.
Just dont use next-auth @GroophyLifefor
Hi GroophyLifefor,
(First > I am not a maintainer just am browsing the adapter implementations and saw your issue here)
I think you need to change how you import your env vars.
These packages are for 2 different environments here.
firebase
more for the client side
firebase-admin
only for the server side
To use the client side library you have to follow next.js rules for environment variables.
https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables
And so for client side code you have to prepend NEXT_PUBLIC
on all of your env vars.
So I expect your client side firebase app is not initiated / will not work when deployed
const firebaseConfig = JSON.parse(process.env.FIREBASE_CONFIG || "");
Suggest for your client side file and firebase import /initialization to change to a config more similar to
const config = {
apiKey: process.env.NEXT_PUBLIC_FB_API_KEY,
appId: process.env.NEXT_PUBLIC_FB_APP_ID,
authDomain: process.env.NEXT_PUBLIC_FB_AUTH_DOMAIN,
databaseURL: process.env.NEXT_PUBLIC_FB_DATABASE_URL,
projectId: process.env.NEXT_PUBLIC_FB_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FB_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FB_MESSAGING_SENDER_ID,
measurementId: process.env.NEXT_PUBLIC_FB_MEASUREMENT_ID,
};
const app = initializeApp(config);
See the next.js repo for their examples and how they explicitly differentiate the client side firebase in its own file etc
And then I understand can be frustrating when coding, but also can consider this project is open source and lot of adapters and surface area to maintain. We can all try and be more considerate of people giving their valuable free time to help the web run smoothly.
If still stuck send me a message and I can help you. I use and have been using the firebase adapter with firebase-admin 11 in next.js projects and working well.
@NickFoden Thank you for your reply and I remember trying this, unfortunately I can't make new attempts to fix because I have removed next-auth from the project and never to use this curse again.
I hope the project gets what it deserves, it's unbelievable that a package supported by Vercel is so bad
note: I use Google's apis and it's easier because at least it works.
In case someone else if facing the same issue, in order to authenticate the user also on the Firebase Authentication dashboard, you just need to use createCustomToken
and signInWithCustomToken
Firebase functions.
For the longer answer, I'll leave you with this exhaustive example here on StackOverflow that I've recently posted (tbh it was related to the Firebase Stripe extension, but the main issue was exactly the one discussed here).
Hope this helps!
import NextAuth,{DefaultSession} from "next-auth"
declare module 'next-auth'{
interface Session{
firebaseToken?:string;
user:{
id:string;
}& DefaultSession["user"]
}
}
adapter for google or github authentications
import {initFirestore} from "@auth/firebase-adapter"
import admin from "firebase-admin"
let app;
if(!admin.apps.length){
app=admin.initializeApp({
credential:admin.credential.cert({
projectId: process.env.FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_PRIVATE_KEY,
}),
});
}
const adminDb=initFirestore({
credential:admin.credential.cert({
projectId: process.env.FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_PRIVATE_KEY,
}),
});
const adminAuth=admin.auth(app);
export{adminDb,adminAuth};
create a components/FirebaseAuthprovider.tsx this for google authentication for call backs and token created
"use client"
import { signInWithCustomToken } from 'firebase/auth';
import { useSession } from 'next-auth/react';
import React, { useEffect } from 'react'
import {auth} from "@/firebase/clientApp"
import { Session } from 'next-auth'
async function syncFirebaseAuth(session: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()
}
}
export default function FirebaseAuthProvider({
children,
}: {
children: React.ReactNode;
}) {
const {data: session}=useSession();
useEffect(()=>{
if(!session) return;
syncFirebaseAuth(session);
},[session])
return<> {children}</>
}
'use client';
import { SessionProvider} from 'next-auth/react';
type Props = {
children: React.ReactNode;
}
export default function ClientProvider({children}: Props) {
return (
<SessionProvider>
{children}
</SessionProvider>
)
}
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import ClientProvider from "@/components/ClientProvider";
import FirebaseAuthProvider from "@/components/FirebaseAuthProvider";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>
<ClientProvider>
{/* <FirebaseAuthProvider> */}
{children}
{/* </FirebaseAuthProvider> */}
</ClientProvider>
</body>
</html>
);
}
if your using google provider wrap that firebaseauthprovider it is not working in credentials provider because firebaseauth provider
use this in auth.ts
import CredentialsProvider from "next-auth/providers/credentials";
import { signInWithEmailAndPassword } from 'firebase/auth';
import { auth } from "@/firebase/clientApp";
import { NextAuthOptions } from "next-auth";
import { FirestoreAdapter } from "@auth/firebase-adapter";
import { adminAuth, adminDb } from "@/firebase/admin";
import Credentials from "next-auth/providers/credentials"
export const authOptions: NextAuthOptions = {
// Configure one or more authentication providers
pages: {
signIn: '/sign-in'
},
session: {
strategy: 'jwt',
},
providers: [
CredentialsProvider({
name: 'Credentials',
credentials: {},
async authorize(credentials): Promise<any> {
try {
const userCredential = await signInWithEmailAndPassword(auth, (credentials as any).email || '', (credentials as any).password || '');
if (userCredential.user) {
return userCredential.user;
}
return null;
} catch (error) {
console.error('Error during sign-in:', error);
throw new Error('Authentication failed');
}
}
})
],
adapter: FirestoreAdapter(adminDb) as any,
callbacks: {
session: async ({ session, token }) => {
if (session?.user) {
if (token.sub) {
session.user.id = token.sub;
const firebaseToken = await adminAuth.createCustomToken(token.sub);
session.firebaseToken = firebaseToken;
}
}
return session;
},
jwt: async ({ user, token }) => {
if (user) {
token.sub = user.id;
}
return token;
},
},
} satisfies NextAuthOptions;
**now next auth is updated Simplify Server-side Authentication: Replace the various server-side authentication with a
methods ( getServerSession
function call in most cases.
getSession
withAuth
getToken
useSession
single
auth()**
In case someone else if facing the same issue, in order to authenticate the user also on the Firebase Authentication dashboard, you just need to use
createCustomToken
andsignInWithCustomToken
Firebase functions.For the longer answer, I'll leave you with this exhaustive example here on StackOverflow that I've recently posted (tbh it was related to the Firebase Stripe extension, but the main issue was exactly the one discussed here).
Hope this helps!
how we can do with credentials provider ? how to store the data in database when sign up session callbacks
@GroophyLifefor did you find a solution here?
@GroophyLifefor did you find a solution here?
Yeah, I found, I never use this .... again.
@GroophyLifefor did you find a solution here?
Yeah, I found, I never use this .... again.
you can use clerk better and easly also i provided u the solve in above for next auth with google credentials , if u want custom sign in and sign up with next auth with firebase it is diffecult
@Saiguna7 I tried your solution, it still was not adding users to the authentication section of firebase.
On Thu, Jun 6, 2024 at 11:55 AM Saiguna7 @.***> wrote:
@GroophyLifefor https://github.com/GroophyLifefor did you find a solution here?
Yeah, I found, I never use this .... again.
you can use clerk better and easly also i provided u the solve in above for next auth with google credentials , if u want custom sign in and sign up with next auth with firebase it is diffecult
— Reply to this email directly, view it on GitHub https://github.com/nextauthjs/next-auth/issues/10280#issuecomment-2153094244, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXDG4OYATT2AS2D6HM3JL2TZGCO75AVCNFSM6AAAAABEQKOZM6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNJTGA4TIMRUGQ . You are receiving this because you commented.Message ID: @.***>
next-auth currently doesn't implement register because it assumes that you have existing users so it only provides signin and signout. as others mentioned if you want to add users to db you can implement that in a callback function or if you want to use firebase you can follow the official documentation here: https://firebase.google.com/codelabs/firebase-nextjs#0 which is way simpler than using next-auth. i would remove next-auth and stick with firebase
@Saiguna7 I tried your solution, it still was not adding users to the authentication section of firebase. … On Thu, Jun 6, 2024 at 11:55 AM Saiguna7 @.> wrote: @GroophyLifefor https://github.com/GroophyLifefor did you find a solution here? Yeah, I found, I never use this .... again. you can use clerk better and easly also i provided u the solve in above for next auth with google credentials , if u want custom sign in and sign up with next auth with firebase it is diffecult — Reply to this email directly, view it on GitHub <#10280 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXDG4OYATT2AS2D6HM3JL2TZGCO75AVCNFSM6AAAAABEQKOZM6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNJTGA4TIMRUGQ . You are receiving this because you commented.Message ID: @.>
Remove credentials provider then it work u can see sonny songa from YouTube creating sass app i did from him https://www.youtube.com/live/OOUsvDOKlGs
Ya but firebase is complex and old for fetching data and role and session update all are complex now I am using supabase with prisma which is very very easy damm it saved a lot supabase is firebase alternative it is very good u need to try
Adapter type
@auth/firebase-adapter
Environment
System:
OS: Windows 11 10.0.22621
CPU: (12) x64 11th Gen Intel(R) Core(TM) i5-11400H @ 2.70GHz
Memory: 1.04 GB / 7.75 GB
Binaries:
Node: 21.6.1 - C:\Program Files\
odejs\
ode.EXE
npm: 10.4.0 - C:\Program Files\
odejs\
pm.CMD
Browsers:
Edge: Chromium (122.0.2365.80)
Internet Explorer: 11.0.22621.1
npmPackages:
@auth/firebase-adapter: ^1.5.0 => 1.5.0
next: 14.1.3 => 14.1.3
next-auth: ^4.24.7 => 4.24.7
react: ^18 => 18.2.0
Reproduction URL
https://github.com/GroophyLifefor/reproduction
Describe the issue
Please READ HERE
First stage - traditional
the auth part of my project is divided into two parts.
route.ts
```ts import { authOptions } from '@/app/options'; import NextAuth from 'next-auth'; const handler = NextAuth(authOptions); export { handler as GET, handler as POST }; ```options.ts
```ts import { NextAuthOptions } from "next-auth"; import GoogleProvider from "next-auth/providers/google"; import FirebaseAdapter from "@next-auth/firebase-adapter"; import { Adapter } from "next-auth/adapters"; export const authOptions: NextAuthOptions = { providers: [ GoogleProvider({ clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, }), ], adapter: FirebaseAdapter as Adapter, secret: "http://127.0.0.1:3000/api/auth", }; ```The problem I'm having here is, first of all, I get an error like this when compiling.
This is like a warning but it says error in Vercel deployment and CI/CD stops.
and when I log in, it doesn't register in firebase.
But it's the only one I can log in, so it's a huge plus. that's is why this way first stage
Second Stage - Carriage
route.ts
```ts import { authOptions } from '@/app/options'; import NextAuth from 'next-auth'; const handler = NextAuth(authOptions); export { handler as GET, handler as POST }; ```options.ts - (M)odified
```ts import { NextAuthOptions } from "next-auth"; import GoogleProvider from "next-auth/providers/google"; import { FirebaseAdapterConfig, FirestoreAdapter } from "@next-auth/firebase-adapter"; import { Adapter } from "next-auth/adapters"; import { connectToDatabaseNotAsync } from "@/lib/firestore"; const { db } = connectToDatabaseNotAsync(); import { getFirestore, collection, query, getDocs, where, limit, doc, getDoc, addDoc, updateDoc, deleteDoc, } from "firebase/firestore"; const firebaseClient = { db, collection, query, getDocs, where, limit, doc, getDoc, addDoc, updateDoc, deleteDoc, }; export const authOptions: NextAuthOptions = { providers: [ GoogleProvider({ clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, }), ], adapter: FirestoreAdapter(firebaseClient as FirebaseAdapterConfig) as Adapter, secret: "http://127.0.0.1:3000/api/auth", }; ```At this stage I no longer get the import error in the build phase, but I get another error that runtime error.
error
```ts bla bla 'Cause'... 14538 more characters, name: 'Error' } [next-auth][error][SESSION_ERROR] https://next-auth.js.org/errors#session_error Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started Error: Unable to detect a Project Id in the current environment. bla bla (very long) (THIS THREE TIMES COMES) at async Server.requestListener (C:\\Users\\Groop\\Desktop\\Desktop\\Code\\javascript\\commentinV2\\commentin\ ode_modules\ ext\\dist\\server\\lib\\start-server.js:140:13) { name: 'GetSessionAndUserError', code: undefined } [next-auth][error][SESSION_ERROR] https://next-auth.js.org/errors#session_error Unable to detect a Project Id in the current environment. bla bla at async Server.requestListener (C:\\Users\\Groop\\Desktop\\Desktop\\Code\\javascript\\commentinV2\\commentin\ ode_modules\ ext\\dist\\server\\lib\\start-server.js:140:13) { name: 'GetUserByAccountError', code: undefined } ```also auth too not working!
Third Stage - With over-research and deep found ways
route.ts
```ts import { authOptions } from '@/app/options'; import NextAuth from 'next-auth'; const handler = NextAuth(authOptions); export { handler as GET, handler as POST }; ```options.ts - (M)odified
```ts import { FirestoreAdapter } from "@auth/firebase-adapter"; import { cert } from "firebase-admin/app"; import { NextAuthOptions } from "next-auth" import { Adapter } from "next-auth/adapters"; import GoogleProvider from "next-auth/providers/google"; import * as admin from 'firebase-admin' export const authOptions: NextAuthOptions = { // 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, }), ], // 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, }), }) as Adapter, callbacks: { async session({ session, token }) { // ... if (token && token.uid) { const firebaseToken = await admin.auth().createCustomToken(token.uid as string) // @ts-ignore session.firebaseToken = firebaseToken } return session }, }, session: { strategy: 'jwt', }, } ```Previously I was only initializing firebase, I was doing it in a file called firestore.ts, I didn't feel the need to add it because there is nothing magical, it just initializes plain.
I imported firebase-admin as
import * as admin from 'firebase-admin'
in this case take care as admin so It's not confict with firebase-app initialize
and finally I have made some changes to my home page,
page.tsx
also mine env was
so provider and adapter values was okey, but still error
error
```ts bla bla [next-auth][error][adapter_error_getUserByAccount] https://next-auth.js.org/errors#adapter_error_getuserbyaccount Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started { message: 'Unable to detect a Project Id in the current environment. \ ' + 'To learn more about authentication and Google APIs, visit: \ ' + 'https://cloud.google.com/docs/authentication/getting-started', stack: 'Error: Unable to detect a Project Id in the current environment. \ ' + 'To learn more about authentication and Google APIs, visit: \ ' + 'https://cloud.google.com/docs/authentication/getting-started\ ' + ' at GoogleAuth.findAndCacheProjectId (C:\\\\Users\\\\Groop\\\\Desktop\\\\Desktop\\\\Code\\\\javascript\\\\commentinV2\\\\commentin\\\ ode_modules\\\\google-auth-library\\\\build\\\\src\\\\auth\\\\googleauth.js:124:19)\ ' + ' at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\ ' + bla bla (very long) 'Cause'... 24114 more characters, name: 'Error' } [next-auth][error][OAUTH_CALLBACK_HANDLER_ERROR] bla bla 2\\commentin\ ode_modules\ ext\\dist\\server\\lib\\router-server.js:377:13) at async Server.requestListener (C:\\Users\\Groop\\Desktop\\Desktop\\Code\\javascript\\commentinV2\\commentin\ ode_modules\ ext\\dist\\server\\lib\\start-server.js:140:13) { name: 'GetUserByAccountError', code: undefined } ```How to reproduce
Actually I couldn't get rid of these errors no matter what I did, if you try to setup it in a normal way you may get these errors.
Expected behavior
error-free, bug-free life