Skip to main content
RapidDev - Software Development Agency
firebase-tutorial

How to Enable Email Verification in Firebase Auth

To enable email verification in Firebase, call sendEmailVerification() on the current user object immediately after signup. Check the user's emailVerified property before granting access to protected features. Configure actionCodeSettings to redirect users back to your app after clicking the verification link. Combine this with Firestore security rules that check request.auth.token.email_verified for server-side enforcement.

What you'll learn

  • How to send a verification email after user signup
  • How to check email verification status before granting access
  • How to customize the verification redirect URL with actionCodeSettings
  • How to enforce email verification in Firestore security rules
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read10-15 minFirebase (Spark and Blaze plans), firebase v9+ modular SDKMarch 2026RapidDev Engineering Team
TL;DR

To enable email verification in Firebase, call sendEmailVerification() on the current user object immediately after signup. Check the user's emailVerified property before granting access to protected features. Configure actionCodeSettings to redirect users back to your app after clicking the verification link. Combine this with Firestore security rules that check request.auth.token.email_verified for server-side enforcement.

Setting Up Email Verification in Firebase Auth

Email verification confirms that a user owns the email address they signed up with. This tutorial covers sending the verification email, checking the verified status, customizing the email template redirect URL, and enforcing verification at both the client and security rules level. You will build a complete verification flow that prevents unverified users from accessing protected resources.

Prerequisites

  • A Firebase project with Authentication enabled
  • Email/Password sign-in provider enabled in the Firebase Console
  • The firebase npm package installed (v9 or later)
  • Basic knowledge of JavaScript/TypeScript

Step-by-step guide

1

Send a verification email after signup

After creating a new user with createUserWithEmailAndPassword, the returned UserCredential contains the user object. Call sendEmailVerification() on this user to trigger a verification email. Firebase sends the email automatically using its built-in email template. The email contains a link that, when clicked, sets the user's emailVerified property to true.

typescript
1import { getAuth, createUserWithEmailAndPassword, sendEmailVerification } from 'firebase/auth'
2
3const auth = getAuth()
4
5async function signUpWithVerification(email: string, password: string) {
6 const userCredential = await createUserWithEmailAndPassword(auth, email, password)
7 const user = userCredential.user
8
9 await sendEmailVerification(user)
10 console.log('Verification email sent to', email)
11
12 return user
13}

Expected result: A verification email arrives in the user's inbox with a link to confirm their email address.

2

Configure the verification redirect URL

By default, the verification link opens Firebase's default action handler. Use actionCodeSettings to redirect users back to your application after they verify their email. The url parameter is where users land after clicking the verification link. Add this URL to the Authorized Domains list in Firebase Console under Authentication > Settings.

typescript
1import { sendEmailVerification } from 'firebase/auth'
2
3const actionCodeSettings = {
4 url: 'https://your-app.com/verified',
5 handleCodeInApp: false,
6}
7
8async function sendVerification(user: any) {
9 await sendEmailVerification(user, actionCodeSettings)
10}

Expected result: After clicking the verification link, users are redirected to your specified URL instead of the default Firebase page.

3

Check email verification status on the client

After the user clicks the verification link, their emailVerified property updates to true. However, the local auth token may be stale. Call reload() on the user object to fetch the latest verification status from the server, then check emailVerified. Use this check to gate access to features that require a verified email.

typescript
1import { getAuth } from 'firebase/auth'
2
3const auth = getAuth()
4
5async function checkVerification() {
6 const user = auth.currentUser
7 if (!user) return false
8
9 // Refresh the user's profile from the server
10 await user.reload()
11
12 if (user.emailVerified) {
13 console.log('Email is verified')
14 return true
15 } else {
16 console.log('Email is not yet verified')
17 return false
18 }
19}

Expected result: The function returns true when the user has clicked the verification link, false otherwise.

4

Gate protected routes based on verification status

Create a wrapper component or middleware that checks emailVerified and redirects unverified users to a prompt page. Listen for auth state changes with onAuthStateChanged, and after detecting a logged-in user, check their verification status. Show a prompt to resend the verification email if the user has not yet verified.

typescript
1import { useEffect, useState } from 'react'
2import { getAuth, onAuthStateChanged, sendEmailVerification, User } from 'firebase/auth'
3
4function useAuth() {
5 const [user, setUser] = useState<User | null>(null)
6 const [verified, setVerified] = useState(false)
7
8 useEffect(() => {
9 const auth = getAuth()
10 const unsubscribe = onAuthStateChanged(auth, async (firebaseUser) => {
11 if (firebaseUser) {
12 await firebaseUser.reload()
13 setUser(firebaseUser)
14 setVerified(firebaseUser.emailVerified)
15 } else {
16 setUser(null)
17 setVerified(false)
18 }
19 })
20 return () => unsubscribe()
21 }, [])
22
23 const resendVerification = async () => {
24 if (user && !user.emailVerified) {
25 await sendEmailVerification(user)
26 }
27 }
28
29 return { user, verified, resendVerification }
30}

Expected result: Unverified users see a verification prompt with a resend button; verified users access the protected content.

5

Enforce verification in Firestore security rules

Client-side checks can be bypassed. Add server-side enforcement by checking email_verified in your Firestore security rules. The request.auth.token object contains email_verified as a boolean. This ensures that even if someone bypasses your UI, they cannot read or write protected data without a verified email.

typescript
1// firestore.rules
2rules_version = '2';
3service cloud.firestore {
4 match /databases/{database}/documents {
5
6 // Only verified users can read or write posts
7 match /posts/{postId} {
8 allow read, write: if request.auth != null
9 && request.auth.token.email_verified == true;
10 }
11
12 // Public data readable by anyone authenticated
13 match /public/{docId} {
14 allow read: if request.auth != null;
15 }
16 }
17}

Expected result: Unverified users receive 'Missing or insufficient permissions' when trying to access protected collections.

Complete working example

email-verification.ts
1import {
2 getAuth,
3 createUserWithEmailAndPassword,
4 sendEmailVerification,
5 onAuthStateChanged,
6 User,
7} from 'firebase/auth'
8
9const auth = getAuth()
10
11const ACTION_CODE_SETTINGS = {
12 url: 'https://your-app.com/verified',
13 handleCodeInApp: false,
14}
15
16export async function signUpAndVerify(
17 email: string,
18 password: string
19): Promise<User> {
20 const { user } = await createUserWithEmailAndPassword(auth, email, password)
21 await sendEmailVerification(user, ACTION_CODE_SETTINGS)
22 return user
23}
24
25export async function resendVerificationEmail(): Promise<void> {
26 const user = auth.currentUser
27 if (!user) throw new Error('No user signed in')
28 if (user.emailVerified) throw new Error('Email already verified')
29 await sendEmailVerification(user, ACTION_CODE_SETTINGS)
30}
31
32export async function isEmailVerified(): Promise<boolean> {
33 const user = auth.currentUser
34 if (!user) return false
35 await user.reload()
36 return user.emailVerified
37}
38
39export function onVerificationChange(
40 callback: (verified: boolean) => void
41): () => void {
42 return onAuthStateChanged(auth, async (user) => {
43 if (user) {
44 await user.reload()
45 callback(user.emailVerified)
46 } else {
47 callback(false)
48 }
49 })
50}

Common mistakes when enabling Email Verification in Firebase Auth

Why it's a problem: Checking emailVerified without calling user.reload() first, seeing stale unverified status

How to avoid: Always call await user.reload() before reading emailVerified. The local auth token caches the old value until refreshed.

Why it's a problem: Not adding the redirect URL to Firebase's Authorized Domains list, causing the verification link to fail

How to avoid: Go to Firebase Console > Authentication > Settings > Authorized Domains and add your app's domain. Without this, Firebase rejects the redirect URL.

Why it's a problem: Only enforcing email verification on the client side, allowing API-level bypasses

How to avoid: Add request.auth.token.email_verified == true to your Firestore security rules for any collection that requires verified users.

Best practices

  • Send the verification email immediately after signup so users can verify while completing onboarding
  • Always call user.reload() before checking emailVerified to get the latest status from the server
  • Add a resend button with a cooldown timer to handle users who did not receive the first email
  • Enforce email verification in Firestore security rules, not just on the client side
  • Customize the actionCodeSettings redirect URL to bring users back to your app after verifying
  • Inform users to check their spam/junk folder if the verification email does not arrive
  • Use Firebase's email template customization in the Console to match your brand

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I want to add email verification to my Firebase Auth signup flow. After a user signs up with email and password, send a verification email, redirect them back to my app after clicking the link, and block access to certain Firestore collections until verified. Show me the complete code.

Firebase Prompt

Implement Firebase email verification in my React app. Send a verification email after signup with a custom redirect URL. Create a useAuth hook that tracks verification status. Add Firestore security rules that require email_verified to be true for the posts collection.

Frequently asked questions

How often can I send verification emails to the same user?

Firebase rate-limits verification emails to 5 per hour per user. If the user exceeds this limit, they must wait before requesting another email.

Can I customize the verification email content?

Yes, go to Firebase Console > Authentication > Templates and edit the Email Verification template. You can change the subject line, body text, and sender name. For full HTML customization, use a custom SMTP server.

Does email verification work with other auth providers like Google?

Google, GitHub, and other OAuth providers typically provide verified emails. The emailVerified property is automatically set to true for these providers. You only need manual verification for email/password signups.

What happens if the user changes their email after verifying?

Changing the email via updateEmail or verifyBeforeUpdateEmail resets emailVerified to false. The user must verify the new email address. Use verifyBeforeUpdateEmail to require verification before the change takes effect.

How do I handle users who sign up but never verify?

Firebase does not automatically delete unverified accounts. You can write a scheduled Cloud Function that queries users via the Admin SDK and deletes accounts that remain unverified after a set period.

Can RapidDev help build a complete authentication flow with email verification?

Yes, RapidDev's team can implement end-to-end Firebase Auth flows including email verification, custom email templates, and server-side enforcement via security rules.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.