Blog

EN
Customize the password recovery flow with Firebase

Customize the password recovery flow with Firebase

4 min read

By default, when a user forgets their password, Firebase sends them to a domain such as your-project.firebaseapp.com. This can undermine user trust and aesthetics.

Is it worth customizing this? For me, absolutely. From my personal experience, it’s much better to customize it. The default option doesn’t inspire much trust and, honestly, it’s a bit ugly. By default, it looks like this:

Reset password en Firebase

How does it work?

When a password reset is requested, Firebase generates a unique code called oobCode, which is sent through a link by Firebase itself. What I’ll do is, instead of using Google’s default page, configure a React app as the official handler for these codes.

Configuration in the Firebase Console

Before going to the code, you need to grant permission to the application. Follow these steps:

  1. Go to Authentication > Settings and add your domain (e.g. my-app.com or localhost).
  2. In Authentication > Templates, select the pencil icon in “Password Reset”. Click on “Edit URL” and change the address to yours: https://my-app.com/auth/action.

Implementation with React

We need two key pieces: an action handler and the new password form.

AuthHandler

This component acts like a “traffic light”. It receives the request from Firebase and decides what to do.

import { useEffect } from 'react';
import { useSearchParams, useNavigate } from 'react-router-dom';

const AuthHandler = () => {
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();

  useEffect(() => {
    const mode = searchParams.get('mode'); // 'resetPassword'
    const oobCode = searchParams.get('oobCode'); // The secret token

    if (mode === 'resetPassword') {
      navigate(`/reset-password?oobCode=${oobCode}`);
    } else {
      navigate('/login');
    }
  }, [searchParams, navigate]);

  return <p>Validating security request...</p>;
};

ResetPassword

Firebase’s confirmPasswordReset method is used to complete the process and apply the password change.

import { confirmPasswordReset, getAuth } from "firebase/auth";

const handleReset = async (newPassword) => {
  try {
    await confirmPasswordReset(auth, oobCode, newPassword);
    alert("Success! You can now sign in.");
  } catch (error) {
    alert("The link has expired or is invalid.");
  }
};

Doing this improves the user experience (UX) and also reinforces security, since users will never feel like they are leaving your application. It also gives a better image and a more professional feel compared to using the default Firebase page.

Share this article on

Avatar byandrev

Andres Parra

Software Engineer

I'm Andres Parra, Software Engineer passionate about developing scalable and innovative technological solutions. I specialize in building modern web applications, mastering a versatile stack that includes JavaScript, TypeScript, Python, and Java, along with frameworks like React, Next.js, and Spring Boot. I'm also interested in the latest technologies and tools for development.