I’m currently working on implementing the sign-up functionality in my Next.js project using AWS Cognito. However, I’ve encountered a frustrating issue. Every time I try to test the sign-up process with a brand-new temporary email address, I receive an error message that says, ‘User already exists.’ This is puzzling because I’m using a completely different temporary email each time I test it, so there shouldn’t be any existing user associated with the email address in the system. I’m not sure what might be causing this issue, and any guidance on how to resolve it would be greatly appreciated!
here’s my signup-form.tsx:
`import { redirect } from "next/navigation";
import {
signUp,
confirmSignUp,
signIn,
signOut,
resendSignUpCode,
autoSignIn,
} from "aws-amplify/auth"
import { getErrorMessage } from "@/utils/get-error-message";
export async function handleSignUp(
prevstate: string | undefined,
formData: FormData
){
try {
const { isSignUpComplete, userId, nextStep } = await signUp({
username: String(formData.get("username")),
password: String(formData.get ("password" )),
options: {
userAttributes: {
email: String(formData.get("email")),
name: String(formData.get ("name")),
},
autoSignIn: true,
},
});
} catch (error) {
return getErrorMessage(error);
}
redirect("/auth/confirm-signup");
}
export async function handleSendEmailVerificationCode(
prevstate: { message: string; errorMessage: string },
formData: FormData
) {
let currentState;
try {
await resendSignUpCode({
username:String(formData.get("email")),
});
currentState = {
...prevstate,
message: "Code sent successfully",
};
} catch (error) {
currentState ={
...prevstate,
errorMessage: getErrorMessage(error),
};
}
return currentState;
}
export async function handleconfirmSignUp(
prevstate: string | undefined,
formData: FormData
) {
try {
const { isSignUpComplete, nextStep } = await confirmSignUp({
username: String(formData.get("email")),
confirmationCode: String(formData.get ("code" )),
});
} catch (error) {
return getErrorMessage(error);
}
redirect("/auth/login");
}
export async function handleSignIn(
prevstate: string | undefined,
formData: FormData
) {
let redirectLink = "/dashboard";
try {
const { isSignedIn, nextStep } = await signIn({
username: String(formData.get("email")),
password: String(formData.get ("password" )),
});
if (nextStep.signInStep === "CONFIRM_SIGN_UP") {
await resendSignUpCode({
username: String(formData.get("email")),
});
redirectLink = "/auth/confirm-signup";
}
} catch (error) {
return getErrorMessage(error);
}
redirect(redirectLink);
}
export async function handleSignOut() {
try {
await signOut();
} catch(error) {
console.log(getErrorMessage(error));
}
redirect("/auth/login");
}`
and cognitoActions.ts:
`"use client";
import { lusitana } from "@/ui/fonts";
import {
AtSymbolIcon,
KeyIcon,
ExclamationCircleIcon,
UserCircleIcon,
} from "@heroicons/react/24/outline";
import { ArrowRightIcon } from "@heroicons/react/20/solid";
import { Button } from "@/ui/button";
import { useFormState, useFormStatus } from "react-dom";
import { handleSignUp } from "@/lib/cognitoActions";
import Link from "next/link";
export default function SignUpForm() {
const [errorMessage, dispatch] = useFormState(handleSignUp, undefined);
return (
<form action={dispatch} className="space-y-3">
<div className="flex-1 rounded-lg bg-gray-50 px-6 pb-4 pt-8 text-black">
<h1 className={`${lusitana.className} mb-3 text-2xl`}>
Please create an account.
</h1>
<div className="w-full">
<div>
<label
className="mb-3 mt-5 block text-xs font-medium text-gray-900 text-black"
htmlFor="name"
>
Name
</label>
<div className="relative">
<input
className="peer block w-full rounded-md border border-gray-200 py-[9px] pl-10 text-sm outline-2 placeholder:text-gray-500"
id="name"
type="text"
name="name"
minLength={4}
placeholder="Enter your name"
required
/>
<UserCircleIcon className="pointer-events-none absolute left-3 top-1/2 h-[18px] w-[18px] -translate-y-1/2 text-gray-500 peer-focus:text-gray-900" />
</div>
</div>
<div className="mt-4">
<label
className="mb-3 mt-5 block text-xs font-medium text-gray-900"
htmlFor="email"
>
Email
</label>
<div className="relative">
<input
className="peer block w-full rounded-md border border-gray-200 py-[9px] pl-10 text-sm outline-2 placeholder:text-gray-500"
id="email"
type="email"
name="email"
placeholder="Enter your email address"
required
/>
<AtSymbolIcon className="pointer-events-none absolute left-3 top-1/2 h-[18px] w-[18px] -translate-y-1/2 text-gray-500 peer-focus:text-gray-900" />
</div>
</div>
<div className="mt-4">
<label
className="mb-3 mt-5 block text-xs font-medium text-gray-900"
htmlFor="password"
>
Password
</label>
<div className="relative">
<input
className="peer block w-full rounded-md border border-gray-200 py-[9px] pl-10 text-sm outline-2 placeholder:text-gray-500"
id="password"
type="password"
name="password"
placeholder="Enter password"
required
minLength={6}
/>
<KeyIcon className="pointer-events-none absolute left-3 top-1/2 h-[18px] w-[18px] -translate-y-1/2 text-gray-500 peer-focus:text-gray-900" />
</div>
</div>
</div>
<LoginButton />
<div className="flex justify-center">
<Link
href="/auth/login"
className="mt-2 mb-4 cursor-pointer text-blue-500 underline"
>
Already have an account? Log in.
</Link>
</div>
<div className="flex h-8 items-end space-x-1">
<div
className="flex h-8 items-end space-x-1"
aria-live="polite"
aria-atomic="true"
>
{errorMessage && (
<>
<ExclamationCircleIcon className="h-5 w-5 text-red-500" />
<p className="text-sm text-red-500">{errorMessage}</p>
</>
)}
</div>
</div>
</div>
</form>
);
}
function LoginButton() {
const { pending } = useFormStatus();
return (
<Button className="mt-4 w-full" aria-disabled={pending}>
Create account <ArrowRightIcon className="ml-auto h-5 w-5 text-gray-50" />
</Button>
);
}`
1