Artificial Intelligence has transformed modern applications, and AI chatbots are now among the most popular software products worldwide. Applications like ChatGPT, Gemini, Claude, and Microsoft Copilot have demonstrated how conversational AI can assist users with coding, writing, research, education, and customer support.
The good news is that you don’t need a massive engineering team to build your own AI chatbot. Using Firebase and Google’s Gemini API, developers can create a production-ready ChatGPT-style application with authentication, chat history, cloud storage, and AI-powered responses.
In this tutorial, you’ll learn how to build a complete ChatGPT clone from scratch using Firebase and Gemini API. By the end of this guide, you’ll have a modern AI chat application capable of storing conversations, authenticating users, and generating intelligent responses using Google’s latest AI models.
What You’ll Build
Our final application will include the following features:
- Google Sign-In Authentication
- Gemini AI Integration
- Real-Time Chat Interface
- Firestore Chat History Storage
- Multiple Conversations
- Typing Indicator
- Responsive Mobile Design
- Firebase Hosting Deployment
- Dark Mode Interface
- Secure Cloud Database
Project Architecture
User ↓ Frontend (HTML + CSS + JavaScript) ↓ Firebase Authentication ↓ Firestore Database ↓ Gemini API ↓ AI Response ↓ Store Conversation History The frontend sends user messages to Gemini, receives AI-generated responses, and stores the entire conversation inside Firestore for future access.
Prerequisites
Before starting, make sure you have:
- Basic HTML, CSS, and JavaScript knowledge
- A Google Account
- A Firebase Account
- A Gemini API Key
- Visual Studio Code
- Node.js Installed (optional for deployment tools)
Create a Firebase Project
Firebase will handle authentication, hosting, and chat history storage.
- Open Firebase Console.
- Click Create Project.
- Enter a project name.
- Continue with default settings.
- Wait for project creation.
After creation, you’ll be redirected to the Firebase dashboard.
Enable Authentication
- Navigate to Authentication.
- Select Get Started.
- Open the Sign-In Method tab.
- Enable Google Provider.
- Save changes.
Users will now be able to sign in using their Google accounts.
Enable Firestore Database
- Open Firestore Database.
- Click Create Database.
- Select Production Mode.
- Choose your nearest region.
- Create the database.
Firestore will store chat messages and user conversations.
Create a Web App
Register your frontend application with Firebase.
- Click the Web icon.
- Enter an application name.
- Register the app.
- Copy the Firebase configuration object.
It will look similar to this:
const firebaseConfig = { apiKey: "YOUR_API_KEY", authDomain: "PROJECT.firebaseapp.com", projectId: "PROJECT_ID", storageBucket: "PROJECT.appspot.com", messagingSenderId: "123456", appId: "APP_ID" }; Get Your Gemini API Key
Gemini powers the AI responses inside our chatbot.
- Open Google AI Studio.
- Create a new API key.
- Copy the generated key.
- Store it securely.
We’ll use this key later when sending requests to Gemini.
Create Project Structure
Create the following files:
chatgpt-clone/ ├── index.html ├── style.css ├── app.js ├── firebase.js └── assets/ This structure keeps the application organized and easy to maintain.
Create the Main HTML Layout
Open index.html and add:
<!DOCTYPE html> <html> <head> <title>AI Chatbot</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <div class="sidebar"> <button id="newChat"> New Chat </button> </div> <div class="chat-area"> <div id="messages"> </div> <div class="input-box"> <input type="text" id="prompt" placeholder="Ask anything..." > <button id="sendBtn"> Send </button> </div> </div> </div> <script src="app.js"></script> </body> </html> Create a Modern ChatGPT-Style Design
Now create style.css.
body{ margin:0; font-family:Arial,sans-serif; background:#202123; color:white; height:100vh; } .container{ display:flex; height:100vh; } .sidebar{ width:250px; background:#171717; padding:20px; } .chat-area{ flex:1; display:flex; flex-direction:column; } #messages{ flex:1; overflow-y:auto; padding:20px; } .input-box{ display:flex; padding:20px; background:#2b2b2b; } .input-box input{ flex:1; padding:12px; border:none; outline:none; border-radius:8px; } .input-box button{ margin-left:10px; padding:12px 20px; cursor:pointer; } This creates a clean dark interface similar to ChatGPT.
Add Message Styles
Append the following CSS:
.message{ padding:15px; margin-bottom:15px; border-radius:10px; max-width:80%; } .user{ background:#343541; margin-left:auto; } .bot{ background:#444654; } User messages and AI responses will now have distinct visual styles.
Responsive Mobile Layout
Add mobile support:
@media(max-width:768px){ .sidebar{ display:none; } .input-box{ padding:10px; } } This ensures the application works smoothly on smartphones and tablets.
Preview the Interface
At this stage, you should have:
- Firebase Project Created
- Authentication Enabled
- Firestore Database Ready
- Gemini API Key Generated
- Modern Chat Interface Built
- Responsive Design Added
The UI is complete. Next, we’ll connect Firebase Authentication, Firestore, and Gemini AI to make the chatbot fully functional.
Configure Firebase SDK
Now that the user interface is ready, it’s time to connect the application to Firebase. We’ll initialize Firebase, enable Google Authentication, and connect Firestore to store chat history.
Create a new file named firebase.js.
// Import Firebase modules
import { initializeApp } from "https://www.gstatic.com/firebasejs/11.9.0/firebase-app.js";
import {
getAuth,
GoogleAuthProvider,
signInWithPopup,
signOut
} from "https://www.gstatic.com/firebasejs/11.9.0/firebase-auth.js";
import {
getFirestore,
collection,
addDoc,
getDocs,
query,
orderBy,
serverTimestamp
} from "https://www.gstatic.com/firebasejs/11.9.0/firebase-firestore.js";
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_PROJECT.firebaseapp.com",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_PROJECT.appspot.com",
messagingSenderId: "YOUR_SENDER_ID",
appId: "YOUR_APP_ID"
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const provider = new GoogleAuthProvider();
export const db = getFirestore(app);
Enable JavaScript Modules
Update your HTML script tag:
<script type="module" src="app.js"></script>
Google Sign-In
Import Firebase inside app.js.
import {
auth,
provider,
db
} from "./firebase.js";
import {
signInWithPopup
} from
"https://www.gstatic.com/firebasejs/11.9.0/firebase-auth.js";
Create the login function:
async function login(){
try{
const result=
await signInWithPopup(
auth,
provider
);
console.log(
result.user.displayName
);
}
catch(error){
console.error(error);
}
}
Call this function when the page loads or attach it to a “Sign in with Google” button.
Create the Send Button Event
const sendBtn=
document.getElementById("sendBtn");
sendBtn.addEventListener(
"click",
sendMessage
);
Read User Input
async function sendMessage(){
const input=
document.getElementById("prompt");
const message=
input.value.trim();
if(message==="") return;
input.value="";
}
Display User Message
function addMessage(text,type){
const div=
document.createElement("div");
div.className=
"message "+type;
div.innerText=text;
document
.getElementById("messages")
.appendChild(div);
}
Inside sendMessage():
addMessage(
message,
"user"
);
Connect to Gemini API
Create your Gemini endpoint:
const API_KEY="YOUR_GEMINI_API_KEY";
const URL=
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${API_KEY}`;
Note: Replace gemini-2.5-flash with another supported model if needed.
Send Prompt to Gemini
const response=
await fetch(URL,{
method:"POST",
headers:{
"Content-Type":
"application/json"
},
body:JSON.stringify({
contents:[
{
parts:[
{
text:message
}
]
}
]
})
});
Read AI Response
const data=
await response.json();
const aiText=
data.candidates[0]
.content.parts[0]
.text;
Display it:
addMessage(
aiText,
"bot"
);
Save Messages to Firestore
Create a collection named messages.
import{
collection,
addDoc,
serverTimestamp
}
from
"https://www.gstatic.com/firebasejs/11.9.0/firebase-firestore.js";
Store the user’s message:
await addDoc(
collection(
db,
"messages"
),
{
role:"user",
text:message,
createdAt:
serverTimestamp(),
uid:
auth.currentUser.uid
}
);
Save Gemini Response
await addDoc(
collection(
db,
"messages"
),
{
role:"assistant",
text:aiText,
createdAt:
serverTimestamp(),
uid:
auth.currentUser.uid
}
);
Firestore Structure
messages
|
|--document
|
|--uid
|--role
|--text
|--createdAt
Each chat message is stored as a separate document, making it easy to retrieve conversation history in chronological order.
Load Previous Messages
const q=
query(
collection(db,"messages"),
orderBy("createdAt")
);
const snapshot=
await getDocs(q);
snapshot.forEach(doc=>{
const data=
doc.data();
addMessage(
data.text,
data.role==="user"
?"user"
:"bot"
);
});
Add a Typing Indicator
Show feedback while waiting for the AI response.
const typing=
document.createElement("div");
typing.className=
"message bot";
typing.id="typing";
typing.innerText=
"Gemini is typing...";
document
.getElementById("messages")
.appendChild(typing);
Remove it after receiving the response:
document
.getElementById("typing")
.remove();
Handle API Errors
try{
// Gemini request
}
catch(error){
addMessage(
"Something went wrong. Please try again.",
"bot"
);
console.error(error);
}
Allow Sending with Enter Key
document
.getElementById("prompt")
.addEventListener(
"keydown",
function(event){
if(event.key==="Enter"){
sendMessage();
}
});
Auto Scroll to Latest Message
const chat=
document
.getElementById("messages");
chat.scrollTop=
chat.scrollHeight;
Call this after adding each message so the latest response is always visible.
Current Application Features
- ✅ Firebase Authentication
- ✅ Google Login
- ✅ Firestore Database
- ✅ Gemini API Integration
- ✅ Send Messages
- ✅ Receive AI Responses
- ✅ Save Chat History
- ✅ Load Previous Messages
- ✅ Typing Indicator
- ✅ Auto Scroll
- ✅ Error Handling
- ✅ Responsive Chat Interface
What’s Coming in Part 2?
- Firestore Security Rules
- Protecting the Gemini API Key
- Using Firebase Cloud Functions as a secure backend
- Deploying to Firebase Hosting
- Performance Optimization
- Markdown & Code Syntax Highlighting
- Multiple Chat Sessions
- Image Upload Support
- Voice Input
- Cost Optimization
- Frequently Asked Questions
- Final Production Checklist
By this stage, your ChatGPT clone can authenticate users, send prompts to Gemini, receive AI-generated responses, and store chat history in Firestore. In Part 2, we’ll make the application production-ready with enhanced security, deployment, and advanced features.


