Skip to main content

Lazy Migration Explained with Code


What is lazy migration?

Lazy migration is a technique used when you want to migrate your database or user accounts gradually. For example, your usernames and passwords are stored in MySQL, but now you are using Firebase for authentication. However, you do not want to lose your existing users. In this case, you can apply lazy migration.

How does it work?

The login page is designed in such a way that it first checks the user's credentials in the old database. If the user is found, the system creates a Firebase account for that user and redirects them to the intended page where they are logged in.

If the user lookup fails, the system shows an error message such as "username or password not available" or may redirect the user to the signup page.

What are the benefits of lazy migration?

  • Existing users can log in seamlessly without facing difficulties.

  • There is no need for users to reset their passwords.

  • New users can directly sign up using the new authentication system.


Backend


import os
import requests
import bcrypt

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel

from sqlalchemy.orm import Session

from passlib.context import CryptContext


# ===========================
# Import your database files
# ===========================
from database import SessionLocal
from models import User

# ===========================
# FastAPI App
# ===========================

app = FastAPI(
    title="Authentication API",
    version="1.0.0"
)

# ===========================
# CORS Middleware
# ===========================

app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "http://localhost:3000",
        "http://localhost:5173",
    ],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


FIREBASE_API_KEY = "FIREBASE_API_KEY"





class LoginRequest(BaseModel):

    email:str

    password:str





class LoginResponse(BaseModel):

    access_token:str

    token_type:str

    role:str


def hash_password(password: str) -> str:
    return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()

def verify_password(plain_password: str, hashed_password: str) -> bool:
    return bcrypt.checkpw(plain_password.encode(), hashed_password.encode())


def create_firebase_user(email,password):


    signup_url = (
        "https://identitytoolkit.googleapis.com/"
        "v1/accounts:signUp?key="
        + FIREBASE_API_KEY
    )



    response = requests.post(

        signup_url,

        json={

            "email":email,

            "password":password,

            "returnSecureToken":True

        }

    )



    result=response.json()



    # User already migrated

    if (
        "error" in result and
        result["error"]["message"]
        == "EMAIL_EXISTS"
    ):



        login_url=(

        "https://identitytoolkit.googleapis.com/"
        "v1/accounts:signInWithPassword?key="
        + FIREBASE_API_KEY

        )



        response=requests.post(

            login_url,

            json={

                "email":email,

                "password":password,

                "returnSecureToken":True

            }

        )



        result=response.json()




    if "idToken" not in result:


        raise HTTPException(

            status_code=500,

            detail="Firebase login failed"

        )



    return result







@app.post(
    "/loginFirebase",
    response_model=LoginResponse
)
def login(data:LoginRequest):



    db=SessionLocal()



    try:


        # CHANGE THIS IF YOUR COLUMN IS username

        user=db.query(User).filter(

            User.username == data.email

        ).first()



    finally:

        db.close()





    if not user:


        raise HTTPException(

            status_code=400,

            detail="Incorrect email or password"

        )






    # Existing bcrypt check

    if not verify_password(

        data.password,

        user.password

    ):


        raise HTTPException(

            status_code=400,

            detail="Incorrect email or password"

        )






    # Lazy migration to Firebase

    firebase_user=create_firebase_user(

        data.email,

        data.password

    )






    return {


        "access_token":

            firebase_user["idToken"],


        "token_type":

            "bearer",


        "role":

            user.role

    }

Frontend

<div id="login-container" style="font-family: sans-serif; margin:auto auto; max-width: 300px;">
  <h2>Login to Access Premium Content</h2>

  <form id="login-form">

    <div style="margin-bottom: 10px;">
      <label>Email:</label><br />
      <input id="username" placeholder="email@example.com" required
        style="box-sizing: border-box; padding: 8px; width: 100%;"
        type="email" />
    </div>

    <div style="margin-bottom: 10px;">
      <label>Password:</label><br />
      <input id="password" required
        style="box-sizing: border-box; padding: 8px; width: 100%;"
        type="password" />
    </div>

    <div id="error-message" style="color:red; margin-bottom:10px;"></div>

    <button id="login-btn"
      style="background: rgb(0,123,255); color:white; cursor:pointer; padding:10px; width:100%; border:none;"
      type="submit">
      Login
    </button>

  </form>

<script type="module">

const loginForm = document.getElementById("login-form");
const errorDisplay = document.getElementById("error-message");
const loginBtn = document.getElementById("login-btn");

const API_URL = "http://localhost:8000/loginFirebase";

loginForm.addEventListener("submit", async (e)=>{

    e.preventDefault();

    errorDisplay.textContent = "";

    loginBtn.disabled = true;
    loginBtn.textContent = "Checking...";

    const email = document.getElementById("username").value;

    const password = document.getElementById("password").value;

    try {

        const response = await fetch(
            API_URL,
            {
                method:"POST",

                headers:{
                    "Content-Type":"application/json"
                },

                body:JSON.stringify({
                    email:email,
                    password:password
                })
            }
        );

        const data = await response.json();

        if(!response.ok){
            throw new Error(
                data.detail || "Login failed"
            );
        }

        localStorage.setItem(
            "firebase_token",
            data.access_token
        );

        localStorage.setItem(
            "role",
            data.role
        );

        window.location.href =
        "https://www.salimwireless.com";

    }

    catch(error){

        errorDisplay.style.color="red";

        errorDisplay.textContent =
        error.message;

        loginBtn.disabled=false;

        loginBtn.textContent="Login";

    }

});

</script>



Contact Us

Name

Email *

Message *

Popular Posts

Online Simulator for ASK, FSK, and PSK Signal Generation

Interactive Digital Signal Processing (DSP) Tutorial and Simulator for ASK, FSK, and BPSK modulation techniques. Try our new Digital Signal Processing Simulator!   •   Interactive ASK, FSK, and BPSK tools updated for 2025. Start Now Digital Modulation Visualizer: ASK, FSK, & BPSK Simulator Learn and visualize binary modulation techniques (ASK, FSK, BPSK) in real-time with adjustable carrier and sampling parameters. Perfect for DSP students and engineers. 📡 ASK Simulator 📶 FSK Simulator 🎚️ BPSK Simulator 📚 More Topics ASK Modulator FSK Modulator BPSK Modulator More Topics 1. ASK (Amplitude Shift Keying) Simulat...

DFTs-OFDM vs OFDM: Why DFT-Spread OFDM Reduces PAPR Effectively (with MATLAB Code)

Understanding PAPR in DFT-spread OFDM vs. Standard OFDM In modern wireless communications like 4G LTE and 5G NR, managing the Peak-to-Average Power Ratio (PAPR) is critical for hardware efficiency. While OFDM is the gold standard for high-speed data, its high PAPR poses significant challenges for mobile devices. This is where DFTs-OFDM (also known as SC-FDMA) comes in. DFT-spread OFDM (DFTs-OFDM) has lower Peak-to-Average Power Ratio (PAPR) because it "spreads" the data in the frequency domain before applying IFFT, making the time-domain signal behave more like a single-carrier signal rather than a multi-carrier one like OFDM. Deeper Explanation: Aspect OFDM DFTs-OFDM Signal Type Multi-carrier Single-carrier-like Process IFFT of QAM directly QAM → DFT → IFFT PAPR Level High (due to many...

UGC NET Electronic Science Previous Year Question Papers with Solutions

Home / Engineering & Other Exams / UGC NET 2026 PYQ ⬇️ Download Papers and Solutions 📋 Exam Pattern 💡 Preparation Tips ❓ FAQs 📊 Exam Highlights: Electronic Science (88) Feature Details Junior Research Fellowship (JRF) ₹37,000 + HRA per month Eligibility M.Sc/M.Tech in Electronics (55%) Validity of Certificate JRF (3 Years) | Lectureship (Lifetime) 📥 Download UGC NET Electronics PDFs Complete collection of previous year question papers, answer keys and explanations for Subject Code 88. Start Downloading 📂 View All Question Papers June 2025 - Question Paper Download PDF June 2025 - Solved Paper + Explanation ...

OFDM Symbols and Subcarriers Explained

This article explains how OFDM (Orthogonal Frequency Division Multiplexing) symbols and subcarriers work. It covers modulation, mapping symbols to subcarriers, subcarrier frequency spacing, IFFT synthesis, cyclic prefix, and transmission. Step 1: Modulation First, modulate the input bitstream. For example, with 16-QAM , each group of 4 bits maps to one QAM symbol. Suppose we generate a sequence of QAM symbols: s0, s1, s2, s3, s4, s5, …, s63 Step 2: Mapping Symbols to Subcarriers Assume N sub = 8 subcarriers. Each OFDM symbol in the frequency domain contains 8 QAM symbols (one per subcarrier): Mapping (example) OFDM symbol 1 → s0, s1, s2, s3, s4, s5, s6, s7 OFDM symbol 2 → s8, s9, s10, s11, s12, s13, s14, s15 … OFDM sym...

Calculation of SNR from FFT bins in MATLAB

📘 Overview 💻 FFT Bin Method 💻 Kaiser Window 📚 Further Reading SNR Estimation Overview In digital signal processing, estimating the Signal-to-Noise Ratio (SNR) accurately is crucial. Below, we demonstrate how to calculate SNR from periodogram and FFT bins using the Kaiser Window . The beta (β) parameter is the key—it allows you to control the trade-off between main-lobe width and side-lobe levels for precise spectral analysis. 1 Define Sampling rate and Time vector 2 Compute FFT and Periodogram PSD 3 Identify Signal Bin and Frequency resolution 4 Segment Signal Power from Noise floor 5 Logarithmic calculation of SNR in dB Method 1: Estimation from FFT Bins This approach uses a Hamming window to estimate SNR directly from the spectral bins. MATLAB Source Code Copy Code clc...

Design of CMOS XOR/XNOR Gates

Design of CMOS XOR/XNOR Gates The semiconductor industry has experienced rapid integration of multimedia applications into mobile electronics, leading to very high integration density in CMOS VLSI. As operating frequencies increase, power consumption, speed, silicon area, and reliability become critical considerations. The XOR-XNOR circuits are fundamental building blocks in arithmetic circuits (Full Adders, Multipliers), compressors, comparators, parity checkers, code converters, error-detecting/correcting codes, and phase detectors. Their performance directly impacts the complex circuits they are used in. Design goals include full output voltage swing, low power consumption, reduced transistor count, minimal delay, and simultaneous non-skewed outputs. Static Logic (Static CMOS) Stat...