# Email/Password and Email Link Sign-in — Firebase

Source: https://www.skillbyai.com/en/firebase/au-email

> The most common starting point.

## Two email flows

With **email/password**, `createUserWithEmailAndPassword` registers a user and `signInWithEmailAndPassword` signs them in; Firebase stores password hashes for you. `sendEmailVerification` and `sendPasswordResetEmail` handle the usual follow-ups. **Email link** (passwordless) sign-in sends a one-time link with `sendSignInLinkToEmail`; when the user opens it, `isSignInWithEmailLink` checks the URL and `signInWithEmailLink` completes sign-in. Each provider must be enabled in the console first. Error codes such as `auth/wrong-password` vary with settings like email enumeration protection, so show generic messages.

## Who is the user?

Firebase Authentication signs users in with many providers and gives each a stable uid and a signed ID token.

![Three ideas: email sign-in, OAuth and anonymous auth, auth state and tokens.](assets/figures/firebase/section-2-map.svg) — Figure 2.1 — Providers, linking and ID tokens.

## Register, sign in and passwordless

TypeScript, modular SDK.

```typescript
import {
  getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword,
  sendEmailVerification, sendSignInLinkToEmail,
  isSignInWithEmailLink, signInWithEmailLink,
} from "firebase/auth";

const auth = getAuth(app);

export async function register(email: string, password: string) {
  const cred = await createUserWithEmailAndPassword(auth, email, password);
  await sendEmailVerification(cred.user);
}

export const login = (email: string, password: string) =>
  signInWithEmailAndPassword(auth, email, password);

export async function sendMagicLink(email: string) {
  await sendSignInLinkToEmail(auth, email, {
    url: "https://my-app.example.com/finish-sign-in",
    handleCodeInApp: true,
  });
  localStorage.setItem("emailForSignIn", email);
}

export async function finishMagicLink() {
  const email = localStorage.getItem("emailForSignIn");
  if (email && isSignInWithEmailLink(auth, window.location.href)) {
    await signInWithEmailLink(auth, email, window.location.href);
    localStorage.removeItem("emailForSignIn");
  }
}
```

## Do not reveal which emails exist

Show the same message for "wrong password" and "no such user", and keep email enumeration protection enabled in the console.

**Quiz:** Which function completes passwordless sign-in after the user opens the emailed link?

- [ ] createUserWithEmailAndPassword
- [x] signInWithEmailLink
- [ ] sendPasswordResetEmail
- [ ] signInAnonymously

*Answer:* signInWithEmailLink. The link carries a one-time code in the URL.
