DEV Community

linou518
linou518

Posted on

Dropping Email Required — Migrating to Phone OR Email Authentication

Background

While building an internal e-commerce site, I put an email required constraint on the registration form from day one. The reason was simple: authentication = email was my unconscious assumption.

Then reality hit. Most existing users only had phone numbers. Specifically, users registered via LINE only had phone numbers in the database — no email addresses. When they tried to register, they got a Bad Request error.

The Problem Structure

The frontend (React) sends phone number + password. The backend (Node.js/TypeScript) looks up users by phone number, but users with email as required field = unset were not processed correctly.

Worse, when a phone number was submitted for new registration but already existed in the DB, it tried to create a new record and hit a Unique constraint violation.

Two problems:

  1. Registration: email as required field causes validation to reject phone-only users
  2. Registration: attempting to create a new user with an existing phone number causes Unique error

Solution

Frontend Changes

Made the email field optional. Removed required attribute and updated the placeholder.

<input
  type="email"
  placeholder="Email (optional)"
  value={email}
  onChange={(e) => setEmail(e.target.value)}
/>
Enter fullscreen mode Exit fullscreen mode

Backend Changes

Unified login/registration logic to accept phone OR email.

// Before: search by email only
const user = await User.findOne({ where: { email } });

// After: search by phone OR email
const user = await User.findOne({
  where: {
    [Op.or]: [
      phone ? { phone } : null,
      email ? { email } : null,
    ].filter(Boolean),
  },
});
Enter fullscreen mode Exit fullscreen mode

Added logic to route existing phone numbers to login instead of registration:

if (existingUser) {
  return handleLogin(existingUser, password);
} else {
  return handleRegister({ phone, email, password });
}
Enter fullscreen mode Exit fullscreen mode

Lessons Learned

Question the assumption that email = primary identifier. In Asia and Southeast Asia, phone numbers are often the primary identifier. This is especially true for LINE or WhatsApp-based businesses.

Do not over-separate registration and login. When these are completely separate APIs, edge cases like phone number exists but the user does not know become hard to handle.

Summary

  • Match auth fields to user reality — use OR not AND
  • Keep frontend validation and backend validation in sync
  • Existing user registration error is a sign of a design assumption mismatch

What looked like a small bug fix revealed a deeper design flaw about what a user really is. Code that matches reality beats code that merely runs correctly.

Top comments (0)