Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[auth][error] MissingAdapter: Email login requires an adapter (firebase adapter and Resend) #10632

Open
tidianeb5 opened this issue Apr 18, 2024 · 8 comments
Labels
adapters Changes related to the core code concerning database adapters bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.

Comments

@tidianeb5
Copy link

tidianeb5 commented Apr 18, 2024

Adapter type

@auth/firebase-adapter

Environment

  System:
    OS: macOS 14.4.1
    CPU: (14) arm64 Apple M3 Max
    Memory: 4.13 GB / 36.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 21.7.3 - /opt/homebrew/bin/node
    Yarn: 1.22.22 - /opt/homebrew/bin/yarn
    npm: 10.5.0 - /opt/homebrew/bin/npm
  Browsers:
    Chrome: 124.0.6367.60
    Safari: 17.4.1
  npmPackages:
    @auth/firebase-adapter: ^1.6.0 => 1.6.0 
    next: ^14.1.4 => 14.2.2 
    next-auth: ^5.0.0-beta.15 => 5.0.0-beta.16 
    react: ^18.2.0 => 18.2.0 

Reproduction URL

https://github.com/tidianeb5/missing-adapter-issues-firebase-adapter-and-resend

Describe the issue

Issue Description

I'm encountering an error when trying to use email login with the next-auth package:

[auth][error] MissingAdapter: Email login requires an adapter. Read more at https://errors.authjs.dev#missingadapter

at assertConfig (webpack-internal:///(middleware)/./node_modules/@auth/core/lib/utils/assert.js:138:24)
at Auth (webpack-internal:///(middleware)/./node_modules/@auth/core/index.js:88:95)

Configuration

I'm using the following configuration:

  • next-auth version: 5.0.0-beta.15

According to the documentation, if you have an adapter that is not compatible with the Edge runtime, you need to separate the configuration into two files.

  1. auth.config.ts:
import type { NextAuthConfig } from "next-auth";

import Resend from "next-auth/providers/Resend"; 


export default {
  providers: [
   Resend
  ],
} satisfies NextAuthConfig;
  1. auth.ts (API Route):
import NextAuth from "next-auth";

import authConfig from "@/auth.config";
import { FirestoreAdapter } from "@auth/firebase-adapter";

import { cert } from "firebase-admin/app";



export const {
  handlers: { GET, POST },
  auth,
  signIn,
  signOut,
} = NextAuth({
  ...authConfig,
  pages: {
    signIn: "/auth/login",
    error: "/auth/error",
  },


  adapter: FirestoreAdapter({
    credential: cert({
      projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID!,
      clientEmail: process.env.SERVICE_ACCOUNT_CLIENT_EMAIL!,
      privateKey: process.env.SERVICE_ACCOUNT_PRIVATE_KEY!.replace(
        /\\n/g,
        "\n"
      ),
    }),
  }),
  session: { strategy: "jwt" },
 
});
  1. [...nextauth].ts (API Route):
export { GET, POST } from "@/auth";
  1. middleware.ts:
import NextAuth from "next-auth";

import authConfig from "@/auth.config";
import {
  DEFAULT_LOGIN_REDIRECT,
  apiAuthPrefix,
  authRoutes,
  publicRoutes,
} from "@/routes";



const { auth } = NextAuth(authConfig);




export default auth((req) => {
  const { nextUrl } = req;
  const isLoggedIn = !!req.auth;

  const isApiAuthRoute = nextUrl.pathname.startsWith(apiAuthPrefix);
  const isPublicRoute = publicRoutes.includes(nextUrl.pathname);
  const isAuthRoute = authRoutes.includes(nextUrl.pathname);

  if (isApiAuthRoute) {
    return null;
  }

  if (isAuthRoute) {
    if (isLoggedIn) {
      return Response.redirect(new URL(DEFAULT_LOGIN_REDIRECT, nextUrl))
    }
    return null;
  }

 

  if (!isLoggedIn && !isPublicRoute) {
    let callbackUrl = nextUrl.pathname;
    if (nextUrl.search) {
      callbackUrl += nextUrl.search;
    }

    const encodedCallbackUrl = encodeURIComponent(callbackUrl);

    return Response.redirect(new URL(
      `/auth/login?callbackUrl=${encodedCallbackUrl}`,
      nextUrl
    ));
  }

  return null;
})

// Optionally, don't invoke Middleware on some paths
export const config = {
  matcher: ['/((?!.+\\.[\\w]+$|_next).*)', '/', '/(api|trpc)(.*)'],
}

Expected Behavior

I expect the email login functionality to work correctly without any errors.

Please let me know if you need any additional information or if I should provide more details about my setup or the steps I've taken to reproduce this issue.

How to reproduce

Just clone the project , and add envs : AUTH_SECRET,SERVICE_ACCOUNT_PRIVATE_KEY,SERVICE_ACCOUNT_CLIENT_EMAIL,NEXT_PUBLIC_FIREBASE_PROJECT_ID ...

Expected behavior

Not showing the error .

@tidianeb5 tidianeb5 added adapters Changes related to the core code concerning database adapters bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime. labels Apr 18, 2024
@NickFoden
Copy link

Hi Mabiri,

I am not a maintainer but saw your issue here and want to give a heads up that next-auth expects firebase-admin of version 11 currently.

if you can try with firebase-admin 11 that might be a path forward. I am trying to raise a PR for updating to firebase-admin 12 at the moment so maybe firebase-admin 12 can work in near future.

Also if you can share any more errors you are getting, does checking types maybe tsc --noEmit flare up any issues from your project ?

@tidianeb5
Copy link
Author

hello NickFoden , thanks for your respond ,

i try firebase-admin version 11.4.1 , but having the same issues ..

@ndom91
Copy link
Member

ndom91 commented Apr 28, 2024

Thanks for pointing this out, it looks liek this is a bug in the assertion process (checking to make sure yuo've added a database adapter) when using an email adapter and also doing the edge-runtime split config.

Basically, it's checking in the edge runtime (where you don't have the adapter in the auth.js config), to ensure that the provider (resend) can operate correctly. But actually, we're not sending any emails in the middleware (edge runtime) anyway, so we can delay that checking to only happen in places where we would actually be sending an email (like in the normal serverles functions / backend / API route).

I'll try to find some time and see where we can make this change. If anyone wants to take a stab that'd be great too :)

EDIT: Notes for later:

@ndom91
Copy link
Member

ndom91 commented Apr 29, 2024

For now, since the Email provider actually isn't doing any work in the middleware / edge runtimes where its throwing this error, you can move your Email provider to the config where you have your adapter as well, so they both don't get included in the middleware / edge runtime enviornments.

That should avoid this error and still have your Resend / whatever Email provider be able to send emails and use up verificationTokens upon signin 👍

@tidianeb5
Copy link
Author

thanks you @ndom91 for your respond , i try mooving the Email provider the config where i have my adapter , but still i am having the same errors...

@matthijsgroen
Copy link

I'm having exactly the same issue :-) Curious about a fix!

@matthijsgroen
Copy link

I tried using a fake adapter in de middleware part. It won't show errors now, but resend does not work either...

The middleware.ts file

import NextAuth from "next-auth";
import { Adapter, VerificationToken } from "next-auth/adapters";
import { authConfig } from "./auth.config";

const fakeEmailAdapter: Adapter = {
  createVerificationToken: (verificationToken: VerificationToken) => undefined,
  useVerificationToken: (params: { identifier: string; token: string }) => null,
  getUserByEmail: (email: string) => null,
};

export default NextAuth({ ...authConfig, adapter: fakeEmailAdapter }).auth;

@tidianeb5
Copy link
Author

I tried using a fake adapter in de middleware part. It won't show errors now, but resend does not work either...

The middleware.ts file

import NextAuth from "next-auth";
import { Adapter, VerificationToken } from "next-auth/adapters";
import { authConfig } from "./auth.config";

const fakeEmailAdapter: Adapter = {
  createVerificationToken: (verificationToken: VerificationToken) => undefined,
  useVerificationToken: (params: { identifier: string; token: string }) => null,
  getUserByEmail: (email: string) => null,
};

export default NextAuth({ ...authConfig, adapter: fakeEmailAdapter }).auth;

did you find a solution ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
adapters Changes related to the core code concerning database adapters bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.
Projects
None yet
Development

No branches or pull requests

4 participants