User going undefined with first page reload
Unanswered
ashcode posted this in #help-forum
ashcodeOP
user is going undefined after being redirected to the dashboard, the page reloads and comes back to the home page, why is that?
not able to persist the user session after page reload.
Should I use getServerSession() or useSession()?
I read somewhere that getServerSession() is more elegant and faster, and you won't also have to wrap your main layout with SessionProvider, is that so?
not able to persist the user session after page reload.
Should I use getServerSession() or useSession()?
I read somewhere that getServerSession() is more elegant and faster, and you won't also have to wrap your main layout with SessionProvider, is that so?
16 Replies
Standard Chinchilla
I prefer getServerSession. However you can only use it in server components. It is elegant and if someone doesn’t have authentication you can redirect them to the login page
It checks if someone is authenticated based on cookies
ashcodeOP
if I use getServerSession(), do I have to still wrap my app with SessionProvider?
I have done something like this,
and using this in components like this,
but I get this error from somewhere, don't know exactly which file.
I was earlier using useSession hook in components, but as soon as I login successfully the router redirects me to dashboard, then then page loads, and I reach back to the login page only, don't know why exactly is this happening.
Also, I thought this might be an issue with page rendering first and the user session being fetched later, so I used getServerSideProps, but I use "app router" and you cannot use that in app router.
Do you happen to know what can I use to load the data first and then render the page in app router? (I read the documentation and it says, with app router you just have to use simple fetch, I don't know how to implement that, I am trying to fetch user data, stored in the session)
Any help would be appreciated, been stuck on it for 5 days now. @Standard Chinchilla
I have done something like this,
import { authOptions } from "../app/api/auth/[...nextauth]/route";
import { getServerSession } from "next-auth/next";
export async function getCurrentUser() {
const session = await getServerSession(authOptions);
return session?.user;
}and using this in components like this,
const user = getCurrentUser();but I get this error from somewhere, don't know exactly which file.
./node_modules/mongodb/lib/client-side-encryption/mongocryptd_manager.js:34:26
Module not found: Can't resolve 'child_process'I was earlier using useSession hook in components, but as soon as I login successfully the router redirects me to dashboard, then then page loads, and I reach back to the login page only, don't know why exactly is this happening.
Also, I thought this might be an issue with page rendering first and the user session being fetched later, so I used getServerSideProps, but I use "app router" and you cannot use that in app router.
Do you happen to know what can I use to load the data first and then render the page in app router? (I read the documentation and it says, with app router you just have to use simple fetch, I don't know how to implement that, I am trying to fetch user data, stored in the session)
Any help would be appreciated, been stuck on it for 5 days now. @Standard Chinchilla
Standard Chinchilla
with getServerSession you do not have to wrap you app in a SessionProvider because you are checking for the user information in the server
That means you can only use getServerSession on the server and it will break in the client
here is an example of a page server component that uses getServerSession:
export default async function Dashboard() {
const session = await getServerSession(authOptions);
if (!(session && session.account)) return redirect(`/api/auth/signin`);
return <Dashboard />
}ashcodeOP
Thanks very much @Standard Chinchilla , so if I want to display user.name in a component, let's say dashboard navbar, then what will I have to do?
also, Do you happen to know what can I use to load the data first and then render the page in app router? (I read the documentation and it says, with app router you just have to use simple fetch, I don't know how to implement that, I am trying to fetch user data, stored in the session) I want to try this and see if my app works well or not because as I login successfully the router redirects me to dashboard, then then page loads, and I reach back to the login page only.
also, Do you happen to know what can I use to load the data first and then render the page in app router? (I read the documentation and it says, with app router you just have to use simple fetch, I don't know how to implement that, I am trying to fetch user data, stored in the session) I want to try this and see if my app works well or not because as I login successfully the router redirects me to dashboard, then then page loads, and I reach back to the login page only.
Standard Chinchilla
Ideally information about the user is encoded inside the session
So what I would do is pass the session user data that I need into the props of the component you want to render
ashcodeOP
I did the same, then;
I am passing the session as a props from layout.js to different components. Why do we get this error, what encryption is it talking about?
also I get this error when the user successfully signin and goes to dashboard but the page reloads and comes back to login;
I am doing optional chaining as well, so I thought that it might be that the data is being fetched late and page is rendering first, so what can I do in this case?
@Standard Chinchilla
I am passing the session as a props from layout.js to different components. Why do we get this error, what encryption is it talking about?
also I get this error when the user successfully signin and goes to dashboard but the page reloads and comes back to login;
MongooseError: Operation `users.findOne()` buffering timed out after 10000msI am doing optional chaining as well, so I thought that it might be that the data is being fetched late and page is rendering first, so what can I do in this case?
@Standard Chinchilla
ashcodeOP
@Standard Chinchilla are you there?
@ashcode <@426730460903768065> are you there?
mind sharing your code?
ashcodeOP
@Dayo Yes sure, so I was getting this error, users.findOne() so I replaced mongoose with the mongoDB driver. I don't have the error any more but my session details are going undefined in the dashboard page; this is my code;
This is my getCurrentUser function
and I am using this in my layout.js and passing it as a prop to page.js and then to dashboard Navbar;
I am using mongoDB adapter for storing user session and details. Also I had some confusion, I;m new to nextjs,
I signed up the user and the user details were automatically stored in a "test" database which had two collections "users" and "accounts", I never defined the schema for it, how did that happen? the mongoDB adapter takes default user values? in case I need to add more models, let's say "products" then what would I do?, simply create the product and whatever fields I pass in the create method, the collection will automatically have those fields?
I wanted to use mongoose only for model schema defining and everything, don't know how can I do that.
This is my getCurrentUser function
import { authOptions } from "../app/api/auth/[...nextauth]/route";
import { getServerSession } from "next-auth/next";
export async function getCurrentUser() {
const session = await getServerSession(authOptions);
return session?.user;
}and I am using this in my layout.js and passing it as a prop to page.js and then to dashboard Navbar;
export default async function DashboardLayout({ children }) {
const user = await getCurrentUser();
return <DashboardPage props={user}>
{children}
</DashboardPage>;
}I am using mongoDB adapter for storing user session and details. Also I had some confusion, I;m new to nextjs,
I signed up the user and the user details were automatically stored in a "test" database which had two collections "users" and "accounts", I never defined the schema for it, how did that happen? the mongoDB adapter takes default user values? in case I need to add more models, let's say "products" then what would I do?, simply create the product and whatever fields I pass in the create method, the collection will automatically have those fields?
I wanted to use mongoose only for model schema defining and everything, don't know how can I do that.
@Dayo
this is how my route.js file looks like in case;
this is how my route.js file looks like in case;
export const authOptions = {
adapter: MongoDBAdapter(clientPromise),
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_SECRET_KEY,
}),
],
pages: {
signIn: "/",
},
secret: process.env.NEXTAUTH_SECRET,
session: {
strategy: "jwt",
},
callbacks: {
async signIn({ user, profile }) {
try {
const client = new MongoClient(process.env.DB_URI)
client.connect();
const db = client.db("test")
const collection = db.collection("users")
let userExits = await collection.findOne({email:profile.email})
// const userExits = await User?.findOne({ email: profile.email });
if (!userExits) {
const res = await axios
.post(`${process.env.NEXTAUTH_URL}/api/user`, {
name: profile.name,
email: profile.email,
image: profile.picture,
})
.then(function (response) {
console.log(response, "this error here");
console.log(response.status, "status");
});
if (res.status === 200) {
return user;
}
}
} catch (err) {
console.log(err, "error from nextjs/auth");
}
return user;
},
async session({ session, token }) {
console.log(session, "this is session");
// const sessionUser = await User.findOne({ email: session.user.email });
// session.user.id = sessionUser._id.toString();
if (session?.user) {
session.user.id = token.sub;
}
return session;
},
},
};My adapter setup, taken from the documentation;
import { MongoClient } from "mongodb";
if (!process.env.DB_URI) {
throw new Error('Invalid/Missing environment variable: "DB_URI"');
}
const uri = `${process.env.DB_URI}/youtubebetter`;
const options = {};
let client;
let clientPromise;
if (process.env.NODE_ENV === "development") {
if (!global._mongoClientPromise) {
client = new MongoClient(uri, options);
global._mongoClientPromise = client.connect();
}
clientPromise = global._mongoClientPromise;
} else {
console.log("I come from the adapter");
client = new MongoClient(uri, options);
clientPromise = client.connect();
}
export default clientPromise;ashcodeOP
@Dayo ??