I'm using the new middleware in nextjs 12 and am trying to add authentication using firebase.
But when i try to use the hook useAuthState
it's giving me an error saying: "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem. null"
I have not made any changes in the app other than creating 2 components both in pages directory
login.js and _middleware.js
here is my _middleware.js
import { NextResponse } from "next/server";
// import firebase from "firebase"
import { initializeApp } from "firebase/app";
import "firebase/auth";
import { getAuth } from "firebase/auth";
import { useAuthState } from "react-firebase-hooks/auth";
initializeApp({
apiKey: "AIzaSyAG1uIhyO0czQtkNNz7mz5kb-0EIfmv4IQ",
authDomain: "clone-3-471b2.firebaseapp.com",
projectId: "clone-3-471b2",
storageBucket: "clone-3-471b2.appspot.com",
messagingSenderId: "954111481882",
appId: "1:954111481882:web:66abeb0cea36775ece19a3",
});
const auth = getAuth();
export async function middleware(req) {
const [user] = useAuthState(auth);
const { pathname } = req.nextUrl;
if (!user) {
return NextResponse.redirect("/login");
}
return NextResponse.next();
}
Here is my login.js
function login() {
const signInWithGoogle = () => {
console.log("Clicked!");
};
return (
<div>
<button onClick={signInWithGoogle}>Sign in with google</button>
</div>
);
}
export default login;
And here's my package.json
{
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"firebase": "^9.5.0",
"next": "^12.0.4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-firebase-hooks": "^4.0.1"
},
"devDependencies": {
"autoprefixer": "^10.2.6",
"postcss": "^8.3.5",
"tailwindcss": "^2.2.4"
}
}
CodePudding user response:
According to React docs
Don’t call Hooks from regular JavaScript functions. Instead, you can:
✅ Call Hooks from React function components.
✅ Call Hooks from custom Hooks (we’ll learn about them on the next page).
So you're using hooks inside regular Javascript function below.
export async function middleware(req) { // this is regular JavaScript function
const [user] = useAuthState(auth); // here you're using hook
const { pathname } = req.nextUrl;
if (!user) {
return NextResponse.redirect("/login");
}
return NextResponse.next();
}
Solution for you case might be
import React, { useEffect } from "react";
import { NextResponse } from "next/server";
import { useAuthState } from "react-firebase-hooks/auth";
function login() {
const [user] = useAuthState(auth); // here you're using hook
const { pathname } = req.nextUrl;
useEffect(() => {
if (!user) {
return NextResponse.redirect("/login");
}
return NextResponse.next();
}, [user]);
const signInWithGoogle = () => {
console.log("Clicked!");
};
return (
<div>
<button onClick={signInWithGoogle}>Sign in with google</button>
</div>
);
}
export default login;
Don't forget to import requried imports in your component
CodePudding user response:
Following nextjs documentation:
next/server
The next/server module provides several exports for server-only helpers, such as Middleware
.
Middleware
Middleware enables you to use code over configuration. This gives you full flexibility in Next.js, because you can run code before a request is completed. Based on the user's incoming request, you can modify the response by rewriting, redirecting, adding headers, or even streaming HTML.
The middleware is not a react component and cannot use hooks.