Obtuve este error en el archivo Next.js _middleware cuando intento inicializar Firebase admin V9. Alguien sabe como solucionar este problema?
./node_modules/@google-cloud/storage/build/src/bucket.js:22:0 Module not found: Can't resolve 'fs' ../../firebase/auth-admin
import * as admin from "firebase-admin"; if (!admin.apps.length) { admin.initializeApp({ credential: admin.credential.cert({ projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, clientEmail: process.env.FIREBASE_CLIENT_EMAIL, privateKey: process.env.FIREBASE_ADMIN_PRIVATE_KEY, }), }); } const firestore = admin.firestore(); const auth = admin.auth(); export { firestore, auth }; Llamándolo en mi _middleware
import { NextFetchEvent, NextRequest, NextResponse } from "next/server"; import { auth } from "../../firebase/auth-admin"; export default async function authenticate( req: NextRequest, ev: NextFetchEvent ) { const token = req.headers.get("token"); console.log("auth = ", auth); // const decodeToken = await auth.verifyIdToken(token); return NextResponse.next(); }Vi una solución aquí al personalizar el paquete web, pero esto no lo soluciona.
/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, webpack: (config, { isServer, node }) => { node = { ...node, fs: "empty", child_process: "empty", net: "empty", tls: "empty", }; return config; }, }; module.exports = nextConfig;Edge Runtime, que utiliza Next.js Middleware, no es compatible con las API nativas de Node.js.
De la documentación de Edge Runtime :
Edge Runtime tiene algunas restricciones que incluyen:
- No se admiten las API nativas de Node.js. Por ejemplo, no puede leer o escribir en el sistema de archivos
- Se pueden usar módulos de nodo, siempre que implementen módulos ES y no usen ninguna API nativa de Node.js
No puede usar bibliotecas de Node.js que usen fs en Next.js Middleware. Intente usar una biblioteca del lado del cliente en su lugar.
Perdí mucho tiempo intentando que esto funcionara. Lo extraño es que esto funcionará en la propia API.
Entonces, en lugar de llamar a la acción firebase-admin en el archivo _middleware . Llámalo en la propia API como:
import type { NextApiRequest, NextApiResponse } from 'next' import { auth } from "../../firebase/auth-admin"; export default async function handler(req: NextApiRequest, res: NextApiResponse) { const authorization = req.headers.authorization console.log(`Handler auth header: ${authorization}`) if (!authorization) { return res.status(401).json({ message: 'Authorisation header not found.' }) } const token = authorization.split(' ')[1] if (!token) { return res.status(401).json({ message: 'Bearer token not found.' }) } console.log(`Token: ${token}`) try { const {uid} = await auth.verifyIdToken("sd" + token) console.log(`User uid: ${uid}`) res.status(200).json({ userId: uid }) } catch (error) { console.log(`verifyIdToken error: ${error}`) res.status(401).json({ message: `Error while verifying token. Error: ${error}` }) } }Una solución para hacer que esto sea reutilizable es crear una función contenedora.
Si alguien sabe cómo hacer que esto funcione en un archivo _middleware , estaría muy agradecido.
Editar: Gist para la función de middleware contenedor: https://gist.github.com/jvgrootveld/ed1863f0beddc1cc2bf2d3593dedb6da
asegúrese de no llamar a firebase-admin en el cliente
import * as admin from "firebase-admin";