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

How to Reset Password in Firebase Auth

To reset a password in Firebase Auth, call sendPasswordResetEmail() with the user's email address. Firebase sends a password reset link to the email. You can customize the email template in the Firebase Console under Authentication > Templates, and configure actionCodeSettings to redirect users back to your app after resetting. Always handle errors like user-not-found and too-many-requests gracefully.

What you'll learn

  • How to send a password reset email using Firebase Auth
  • How to customize the reset email template and redirect URL
  • How to handle the password reset action in your app
  • How to handle common errors in the password reset flow
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate9 min read10-15 minFirebase JS SDK v9+, Firebase Auth, all plansMarch 2026RapidDev Engineering Team
TL;DR

To reset a password in Firebase Auth, call sendPasswordResetEmail() with the user's email address. Firebase sends a password reset link to the email. You can customize the email template in the Firebase Console under Authentication > Templates, and configure actionCodeSettings to redirect users back to your app after resetting. Always handle errors like user-not-found and too-many-requests gracefully.

Implementing Password Reset in Firebase Auth

Firebase Auth provides a built-in password reset flow for email/password accounts. This tutorial walks you through sending the reset email, customizing the email template and redirect behavior, handling the reset action link in your app, and confirming the password change. You will also learn how to handle edge cases like invalid emails, expired links, and rate limiting.

Prerequisites

  • A Firebase project with Authentication enabled
  • Email/Password sign-in method enabled in Firebase Console > Authentication > Sign-in method
  • Firebase JS SDK v9+ installed in your project
  • A working sign-in flow so users have existing accounts to reset

Step-by-step guide

1

Send a password reset email

Use the sendPasswordResetEmail() function from the Firebase Auth SDK. Pass the auth instance and the user's email address. Firebase sends a pre-built email with a password reset link. The function is fire-and-forget from the user's perspective, but you should handle errors to provide good UX. For security, do not reveal whether the email exists in your system to prevent email enumeration.

typescript
1import { getAuth, sendPasswordResetEmail } from 'firebase/auth';
2
3const auth = getAuth();
4
5async function handlePasswordReset(email: string) {
6 try {
7 await sendPasswordResetEmail(auth, email);
8 // Always show success message even if email doesn't exist
9 // This prevents email enumeration attacks
10 console.log('Password reset email sent');
11 } catch (error: any) {
12 switch (error.code) {
13 case 'auth/invalid-email':
14 console.error('Invalid email address format');
15 break;
16 case 'auth/too-many-requests':
17 console.error('Too many attempts. Please try again later.');
18 break;
19 default:
20 console.error('Error sending reset email:', error.message);
21 }
22 }
23}

Expected result: Firebase sends a password reset email to the specified address if the account exists.

2

Configure actionCodeSettings for redirect

Pass an actionCodeSettings object to sendPasswordResetEmail() to control where users are redirected after clicking the reset link. The url property specifies your app's URL where the password reset will be completed. This is especially important for single-page applications and mobile apps. Add the redirect URL to your authorized domains in Firebase Console > Authentication > Settings > Authorized domains.

typescript
1import { getAuth, sendPasswordResetEmail, ActionCodeSettings } from 'firebase/auth';
2
3const auth = getAuth();
4
5const actionCodeSettings: ActionCodeSettings = {
6 url: 'https://your-app.com/auth/reset-complete',
7 handleCodeInApp: true
8};
9
10async function sendReset(email: string) {
11 try {
12 await sendPasswordResetEmail(auth, email, actionCodeSettings);
13 console.log('Reset email sent with custom redirect');
14 } catch (error: any) {
15 console.error('Error:', error.message);
16 }
17}

Expected result: The password reset email links back to your specified URL with an oobCode query parameter.

3

Customize the email template

Firebase provides a default password reset email template that you can customize. In the Firebase Console, go to Authentication > Templates > Password reset. You can edit the subject line, sender name, message body, and action URL. The template supports placeholders like %APP_NAME%, %LINK%, and %EMAIL%. For fully custom emails, use Firebase Admin SDK server-side to generate the reset link and send it through your own email provider.

typescript
1// Server-side: Generate a custom reset link with Admin SDK
2import { getAuth } from 'firebase-admin/auth';
3
4async function generateCustomResetLink(email: string) {
5 const auth = getAuth();
6 const actionCodeSettings = {
7 url: 'https://your-app.com/auth/reset-complete'
8 };
9
10 const link = await auth.generatePasswordResetLink(
11 email,
12 actionCodeSettings
13 );
14
15 // Send the link via your own email service
16 // await sendCustomEmail(email, link);
17 return link;
18}

Expected result: Users receive a branded password reset email with your custom subject, message, and redirect URL.

4

Handle the reset action link in your app

When users click the password reset link, they are redirected to your app with an oobCode (out-of-band code) in the URL query parameters. Extract this code, verify it with verifyPasswordResetCode() to get the associated email, then prompt the user for a new password. Finally, call confirmPasswordReset() with the code and the new password to complete the reset.

typescript
1import {
2 getAuth,
3 verifyPasswordResetCode,
4 confirmPasswordReset
5} from 'firebase/auth';
6
7const auth = getAuth();
8
9async function handleResetAction(oobCode: string, newPassword: string) {
10 try {
11 // Verify the code is valid and get the associated email
12 const email = await verifyPasswordResetCode(auth, oobCode);
13 console.log('Reset code valid for:', email);
14
15 // Confirm the password reset
16 await confirmPasswordReset(auth, oobCode, newPassword);
17 console.log('Password has been reset successfully');
18
19 // Optionally sign the user in automatically
20 // await signInWithEmailAndPassword(auth, email, newPassword);
21 } catch (error: any) {
22 switch (error.code) {
23 case 'auth/expired-action-code':
24 console.error('Reset link has expired. Please request a new one.');
25 break;
26 case 'auth/invalid-action-code':
27 console.error('Reset link is invalid or has already been used.');
28 break;
29 case 'auth/weak-password':
30 console.error('Password is too weak. Use at least 6 characters.');
31 break;
32 default:
33 console.error('Error resetting password:', error.message);
34 }
35 }
36}

Expected result: The user's password is changed to the new password and they can sign in with it immediately.

5

Build a password reset form component

Create a complete React component that handles both the reset request and the reset confirmation. The component checks the URL for an oobCode parameter to determine which view to show: the email input form for requesting a reset, or the new password form for completing the reset.

typescript
1import { useState, useEffect } from 'react';
2import {
3 getAuth,
4 sendPasswordResetEmail,
5 verifyPasswordResetCode,
6 confirmPasswordReset
7} from 'firebase/auth';
8
9function PasswordReset() {
10 const auth = getAuth();
11 const [email, setEmail] = useState('');
12 const [newPassword, setNewPassword] = useState('');
13 const [message, setMessage] = useState('');
14 const [oobCode, setOobCode] = useState<string | null>(null);
15
16 useEffect(() => {
17 const params = new URLSearchParams(window.location.search);
18 const code = params.get('oobCode');
19 if (code) setOobCode(code);
20 }, []);
21
22 const handleSendReset = async () => {
23 try {
24 await sendPasswordResetEmail(auth, email);
25 setMessage('Check your email for a reset link.');
26 } catch {
27 setMessage('Something went wrong. Try again.');
28 }
29 };
30
31 const handleConfirmReset = async () => {
32 if (!oobCode) return;
33 try {
34 await confirmPasswordReset(auth, oobCode, newPassword);
35 setMessage('Password reset! You can now sign in.');
36 } catch {
37 setMessage('Link expired or invalid. Request a new one.');
38 }
39 };
40
41 // Render either the request form or the confirm form
42}

Expected result: Users can request a password reset and complete it within your application without leaving to an external page.

Complete working example

password-reset.ts
1import {
2 getAuth,
3 sendPasswordResetEmail,
4 verifyPasswordResetCode,
5 confirmPasswordReset,
6 signInWithEmailAndPassword,
7 ActionCodeSettings
8} from 'firebase/auth';
9import { initializeApp } from 'firebase/app';
10
11const app = initializeApp({
12 apiKey: 'YOUR_API_KEY',
13 authDomain: 'YOUR_PROJECT.firebaseapp.com',
14 projectId: 'YOUR_PROJECT_ID'
15});
16
17const auth = getAuth(app);
18
19const actionCodeSettings: ActionCodeSettings = {
20 url: 'https://your-app.com/auth/reset-complete',
21 handleCodeInApp: true
22};
23
24export async function requestPasswordReset(email: string): Promise<string> {
25 try {
26 await sendPasswordResetEmail(auth, email, actionCodeSettings);
27 return 'If an account exists with this email, a reset link has been sent.';
28 } catch (error: any) {
29 if (error.code === 'auth/too-many-requests') {
30 return 'Too many attempts. Please wait before trying again.';
31 }
32 if (error.code === 'auth/invalid-email') {
33 return 'Please enter a valid email address.';
34 }
35 return 'An error occurred. Please try again.';
36 }
37}
38
39export async function completePasswordReset(
40 oobCode: string,
41 newPassword: string
42): Promise<{ success: boolean; message: string; email?: string }> {
43 try {
44 const email = await verifyPasswordResetCode(auth, oobCode);
45 await confirmPasswordReset(auth, oobCode, newPassword);
46
47 // Auto sign-in after reset
48 await signInWithEmailAndPassword(auth, email, newPassword);
49
50 return {
51 success: true,
52 message: 'Password reset successfully. You are now signed in.',
53 email
54 };
55 } catch (error: any) {
56 const messages: Record<string, string> = {
57 'auth/expired-action-code': 'This reset link has expired. Request a new one.',
58 'auth/invalid-action-code': 'This reset link is invalid or already used.',
59 'auth/weak-password': 'Password must be at least 6 characters.'
60 };
61 return {
62 success: false,
63 message: messages[error.code] || 'Failed to reset password.'
64 };
65 }
66}

Common mistakes when resetting Password in Firebase Auth

Why it's a problem: Revealing whether an email exists by showing different messages for existing vs non-existing accounts

How to avoid: Always show a generic success message like 'If an account exists, a reset link has been sent.' This prevents email enumeration attacks where attackers probe for valid email addresses.

Why it's a problem: Not adding the redirect URL to the authorized domains list in Firebase Console

How to avoid: Go to Firebase Console > Authentication > Settings > Authorized domains and add the domain used in your actionCodeSettings URL. Without this, users see a 'domain not authorized' error.

Why it's a problem: Assuming the oobCode in the URL never expires

How to avoid: Password reset codes expire after 1 hour and can only be used once. Always handle the auth/expired-action-code and auth/invalid-action-code errors and prompt users to request a new reset email.

Best practices

  • Show a generic success message regardless of whether the email exists to prevent enumeration attacks
  • Use actionCodeSettings to redirect users back to your app after clicking the reset link
  • Customize the email template in Firebase Console to match your brand
  • Validate the new password on the client side before calling confirmPasswordReset()
  • Handle all error codes including expired-action-code, invalid-action-code, and weak-password
  • Consider auto-signing the user in after a successful password reset for better UX
  • Add rate limiting UI feedback to inform users about the 5 emails per hour limit
  • Log password reset events for security auditing purposes

Still stuck?

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

ChatGPT Prompt

Walk me through implementing a complete password reset flow in Firebase Auth including sending the reset email with custom actionCodeSettings, handling the reset link in my app, and error handling for expired and invalid codes.

Firebase Prompt

Write a complete Firebase Auth password reset module in TypeScript using modular SDK v9 with sendPasswordResetEmail, verifyPasswordResetCode, and confirmPasswordReset. Include custom actionCodeSettings and comprehensive error handling for all auth error codes.

Frequently asked questions

How long does a Firebase password reset link last?

Password reset links expire after 1 hour. If a user clicks an expired link, they will see an error. Your app should handle the auth/expired-action-code error and prompt the user to request a new reset email.

Can I customize the password reset email content?

Yes. Go to Firebase Console > Authentication > Templates > Password reset to edit the subject, sender name, and body text. For fully custom emails with your own design, use the Admin SDK's generatePasswordResetLink() to get the link and send it via your own email service.

What happens if the user's email doesn't exist in Firebase Auth?

By default, sendPasswordResetEmail() throws an auth/user-not-found error. However, if you enable Email enumeration protection in Firebase Console > Authentication > Settings, the function succeeds silently. Either way, show a generic success message to prevent email enumeration.

Can I set minimum password requirements for the new password?

Firebase enforces a minimum password length of 6 characters. For stricter requirements, validate the password on the client side before calling confirmPasswordReset(). Firebase does not have built-in complexity rules, so implement those checks in your app.

Does password reset work with OAuth accounts (Google, GitHub)?

No. Password reset only applies to email/password accounts. If a user signed up with Google or GitHub OAuth, they do not have a Firebase password to reset. Their authentication is managed by the OAuth provider.

Can I send password reset emails programmatically from the server?

Yes. Use the Firebase Admin SDK's getAuth().generatePasswordResetLink(email, actionCodeSettings) to generate the reset link server-side, then send it via your own email service like SendGrid or Mailgun for full control over the email design.

Can RapidDev help build a custom password reset flow?

Yes. RapidDev can implement a fully customized password reset experience including branded email templates, custom redirect flows, server-side link generation, and integration with your existing email service provider.

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.