next.jsnext.js13supabasesupabase-database

Handling Sign Up with Existing Email in Supabase


I'm working on a sign-up feature using Supabase and I want to provide feedback to the user if they try to sign up with an email that already exists in the system. However, I'm facing a challenge in detecting this specific case.

When I attempt to sign up with an email that already exists, I receive the following response:

{
  "data": {
    "session": null,
    "user": {
      "id": "b84ad9fb-9f81-42c4-9c5b-3d08b5e04156",
      "aud": "authenticated",
      "role": "authenticated",
      "email": "example@email.com",
      "phone": "",
      ...
    }
  },
  "error": null
}

I understand that Supabase returns this response to avoid leaking information about existing email addresses, but I'm unsure how to handle this case in my application.

  1. Is there a recommended way to detect that the email is already in use and provide appropriate feedback to the user?
  2. Should I use a condition like if (error == null) to handle this case, or is there a more specific approach I should take?

I appreciate any guidance or best practices for handling this scenario in a secure and user-friendly way. Thank you!

Update on 07/09/2023:

I've added a workaround to handle this scenario in my application. Here's the full code snippet:

const handleSignUp = async () => {
  const response = await supabase.auth.signUp({
    email,
    password,
    options: {
      emailRedirectTo: `${location.origin}/auth/callback`,
    },
  });

  // Log the sign-up response
  console.log("Sign-up response:", JSON.stringify(response, null, 2));

  if (response.data && response.data.user) {
    // Log the identities array
    console.log("Identities array:", JSON.stringify(response.data.user.identities, null, 2));
    
    // Check if the user got created
    if (response.data.user.identities && response.data.user.identities.length > 0) {
      console.log("Sign-up successful!");
    } else {
      console.log("Email address is already taken.");
      const signInResponse = await supabase.auth.signInWithPassword({
        email,
        password,
      });

      if (signInResponse.error) {
        console.error("An error occurred during sign-in:", signInResponse.error.message);
      } else {
        console.log("Successfully signed in existing user!");
      }
    }
  } else {
    console.error("An error occurred during sign-up:", response.error?.message);
  }

  router.refresh();
};

Solution

  • This is actually by design, and you should handle sign-up with a duplicate email address as a regular sign-up.

    When a user signs up for the first time, they will get a confirmation email, and you probably will show a snack bar or something telling the user to check their email inbox and confirm the email. When a user who has already signed up tries to sign up again, Supabase will send them a magic link login email to the user, and upon clicking the link will sign them in. As far as you, the application developer does not need to know if the user has already signed up or not. Supabase will handle the case automatically.

    More on this behavior here: https://github.com/supabase/supabase-js/issues/296#issuecomment-976200828