Generative AI (GenAI) Using Gemini 3 Flash with Memory Capability

posted 6 min read

Gemini 3 flash is a generative ai designed by Google for tasks that require high speed and efficiency. It is a large language model often used with prompt engineering to improve its performance. This tutorial is aimed at walking you through on how to integrate gemini 3 flash preview. Required Technologies:

  1. JavaScript
  2. Node.js APIs
  3. Mongodb, mongoose

Here is a step by step guide to follow:

Step 1: Download and install node.js. visit node.js official website here

then also initialize node using
npm init -y
This initializes your node js application with a '-y' flag i.e a yes to all the prompts

Step 2: Visit gemini api docs and get your free api key. here

You can rename the api to 'apiKey'
Then create a dotenv file and paste it as follows
GEMINI_API_KEY = the-api-key-from-above-here

Step 3: Install the necessary packages using npm(node package manager)

npm i @google/genai bcryptjs connect-mongo cors dotenv express express-session mongoose nodemon

where :
@google/genai is the gemini ai installation
bcryptjs is used for password hashing before storing in the database
connect-mongo is used to persist session in the mongodb database as against memory
cors(Cross-Origin Resource Sharing) helps us to make requests to the backend from another domain
dotenv helps us access secret information in our environment variable file e.g GEMINI_API_KEY. and it goes like this process.env.GEMINI_API_KEY
express is a library for routing, middleware, request and response etc
express-session is the standard middleware for managing user sessions in Express.js.
Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js.
nodemon is a node monitor. It monitors files for changes and refreshes automatically.

Quickly make some changes in your package.json file

"scripts": {
"start": "node app.js",
"dev": "nodemon app.js"
}
To use nodemon run :
npm run dev

Step 4: sign up to mongodb atlas for a free connection string here

You can actually use any database of your choice

Step 5: Database Schema for users and chats

A schema defines the structure of documents in a MongoDB collection.
// User Schema:

const mongoose = require('mongoose')

const userSchema = mongoose.Schema({

name:{
    type:String,
    required:[true,"user name is required"],
    trim: true
},
email:{
    type:String,
    required:[true,"user email is required"],
    unique: true, // Prevents duplicate accounts
    lowercase: true, // Converts email to lowercase
    trim: true
},
password:{
    type:String,
    required:[true,"user password is required"]
},

},{timestamps:true})

const User = mongoose.model('User',userSchema)
module.exports = User

 // Chat Schema

const mongoose = require('mongoose')

const ChatSchema = new mongoose.Schema({

userId:{type:mongoose.Schema.Types.ObjectId, ref:'User'},
// use an array of objects to store the conversation flow
messages:[{
    role:{type:String,enum:['user','model'],required:true},
    parts:{type:String,required:true},
    timestamp:{type:Date,default:Date.now}
}],
// New: Store a short bio/summary of what the user like

})

const Chat = mongoose.model('Chat',ChatSchema)
module.exports = Chat

Step 6: Connect to the database

// config/db.js

const mongoose = require('mongoose')

const connectDB = async()=>{

try {
    const conn = await mongoose.connect(process.env.MONGODB_URI)
    console.log(`Connected: ${conn.connection.host} ${conn.connection.name}`)
    
} catch (error) {
    console.log(error.message)
}

}

module.exports = connectDB

Step 7: At this point, let's see folders and modules

      // controllers/userController.js

const User = require('../models/userModel')
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')

// Register user
exports.register = async(req,res)=>{

// getting user details from the html or api tester
const {name,email,password} = req.body
//check if email exists
const isUser = await User.findOne({email})
if(isUser){
   return res.send('User already exists') 
}
// hashing the password
const hashedPassword = await bcrypt.hash(password,10)
// bundling user info to be saved on the database
const user = new User({
    name:name,
    email:email,
    password:hashedPassword
})
try {
    // save user
    const newUser = await user.save()
    if(!newUser){
        res.status(401).json({msg:"Sorry, we could not register user"})
    }
    // return the new user to the frontend
    res.status(201).json({newUser})
} catch (error) {
    res.send(error.message)
}

}

// login logic
exports.login = async (req, res) => {

// getting user inputs from the html forms or api testers(e.g postman)
const { email, password } = req.body;
try {
    // checking if user exists
    const user = await User.findOne({ email });
    if (!user) return res.status(404).json({ message: "User not found" });
    // comparing the password
    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) return res.status(401).json({ message: "Invalid credentials" });

    // Set the session
    req.session.userId = user._id.toString();
    
    // Explicitly save the session before sending the response
    req.session.save((err) => {
        if (err) return res.status(500).json({ message: "Session save failed" });
        return res.status(200).json({ msg: 'Logged in successfully!' });
    });

} catch (error) {
    res.status(500).json({ message: error.message });
}

};

exports.logout = async(req,res)=>{

res.session.destroy(err=>{
    if(err){
        return res.status(500).json({msg:"Logout failed"})
    }
    res.clearCookie('connect.sid')
    res.status(200).json({msg:'Logded out'})
})

}

     // controllers/chatController.js

             
         const Chat = require('../models/chatModel')

const User = require('../models/userModel')
// import { GoogleGenAI } from "@google/genai";
const {GoogleGenAI} = require('@google/genai')

/**

  • This line of code is the initialization step for using Google’s generative AI models
  • (like Gemini 3 Flash) in a Node.js application.
  • It effectively "unlocks" the library so your code can talk to Google's servers.
    */
    const ai = new GoogleGenAI({
    apiKey: process.env.GEMINI_API_KEY, // Access the key securely

});

// Create chat
exports.chat = async (req, res) => {
try {

const userId = req.session.userId; // This comes from the frontend. Sends to your browser upon login
// checking if user exists
if (!userId) {
  return res.status(401).json({ message: "Not logged in" });
}

// 1. Fetch previous memory
const chatData = await Chat.findOne({ userId });
// javaScript ternary operator. if 'chatData' above has value,get the message property. empty array if none
const history = chatData ? chatData.messages : [];

// 2. Format for Gemini (with safety filter)

const context = history
.filter(msg => msg.parts && msg.parts.trim() !== "") // Remove empty messages
.map(msg => ({

role: msg.role === "model" ? "model" : "user", // Ensure role is exactly right
parts: [{ text: msg.parts }]

}));

// 3. Add new user message (with safety check)
const userPrompt = req.body.prompt;
if (!userPrompt || userPrompt.trim() === "") {
return res.status(400).json({ error: "Prompt cannot be empty" });
}

context.push({
role: "user",
parts: [{ text: userPrompt }]
});

// 4. Send to AI
const response = await ai.models.generateContent({
  model: "gemini-3-flash-preview",
  contents: context
});

const aiReply = response.text;

// 5. Save only last exchange
await Chat.findOneAndUpdate(
  { userId },
  {
    $push: {
      messages: {
        $each: [
          { role: "user", parts: req.body.prompt },
          { role: "model", parts: aiReply }
        ],
        $slice: -20
      }
    }
  },
  { upsert: true, new: true }
);

// return res.send([{user:req.body.prompt,model:aiReply}]);
const info = await Chat.findOne({userId})
res.send(info.messages)

} catch (error) {

// console.error(error);
res.status(500).json({ error: error.message });

}
};

// Get user chat

exports.getChat = async(req,res)=>{
const userId = req.session.userId;
if(!userId) return res.send("You must be logged in")

try {

const info = await Chat.findOne({userId})
if(!info){

res.send("User info not found")

}else{

res.send(info.messages)

}

} catch (error) {
      res.status(500).json({ error: error.message });

}

}

                       // routes/ userRoute.js
                
                    const { register, login, logout } = require("../controllers/userController");

const express = require('express')

const router = express.Router()

router.post('/register',register);
router.post('/login',login)
router.post('/logout',logout)

module.exports = router

                      // routes/chatRoute.js
                             const { chat, getChat } = require("../controllers/chatController");

const express = require('express')

const router = express.Router()

router.post('/api/chat',chat)
router.get('/api/chat',getChat)

module.exports = router

                                           // app.js
                                const express = require('express')

const dotenv = require('dotenv').config()
const session = require('express-session')
const MongoStore = require('connect-mongo').default
const connectDB = require('./config/db')
const UserRoutes = require('./routes/userRoute')
const ChatRoute = require('./routes/chatRoute')
const cors = require('cors')

const app = express()
app.set("trust proxy", 1);

connectDB()

app.use(express.json())
// app.use(cors())
app.use(cors({
origin: 'https://domain.com', // Replace with your actual frontend URL
credentials: true
}));
app.use(express.urlencoded({extended:false}))
// app.set("trust proxy", 1);

app.use(session({
name: "sid",
secret: process.env.SESSION_SECRET_KEY,
resave: false,
saveUninitialized: false,
store: MongoStore.create({

mongoUrl: process.env.MONGODB_URI,
collectionName: 'sessions',

}),
cookie: {

maxAge: 1000 * 60 * 60 * 24,
httpOnly: true,
secure: true,
sameSite: "none"

}
}));

app.use('/api/auth',UserRoutes)
app.use('/',ChatRoute)

app.get('/',(req,res)=>{

res.send('Hello AI')

})

const port = process.env.PORT || 7000

app.listen(port,()=>{

console.log(`http://localhost:${port}`)

})

Thanks for taking out your time to read this. Please try something. Build something. Break something

follow my youTube channel for tutorials

2 Comments

1 vote
1
2 votes
2

More Posts

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelskiverified - Mar 19

Memory is Not a Database: Implementing a Deterministic Family Health Ledger

Huifer - Jan 21

AI Reliability Gap: Why Large Language Models are not for Safety-Critical Systems

praneeth - Mar 31

AI Grounding: Connecting local data to live stock prices using Gemini 1.5

Pocket Portfolioverified - Mar 5

Gemini 2.5 Flash vs Claude 3.7 Sonnet: 4 Production Constraints That Made the Decision for Me

Dumebi Okoloverified - Mar 11
chevron_left

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!