Skip to main content
RapidDev - Software Development Agency
flutterflow-tutorials

How to Implement a Chatbot for Customer Support in FlutterFlow

Build an AI-powered customer support chatbot using a Cloud Function that calls the OpenAI Chat Completions API with your support knowledge base as a system prompt. Display messages in a reversed ListView with distinct user and bot bubbles. Store conversation history in Firestore and implement a sliding window to control API costs. Add a live agent handoff that escalates the conversation when the bot cannot resolve the issue after three attempts.

What you'll learn

  • How to build a chat UI with reversed ListView and styled message bubbles
  • How to create a Cloud Function that calls OpenAI with your knowledge base context
  • How to manage conversation history with a sliding window to control API costs
  • How to implement live agent handoff when the bot cannot resolve an issue
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner10 min read25-30 minFlutterFlow Free+March 2026RapidDev Engineering Team
TL;DR

Build an AI-powered customer support chatbot using a Cloud Function that calls the OpenAI Chat Completions API with your support knowledge base as a system prompt. Display messages in a reversed ListView with distinct user and bot bubbles. Store conversation history in Firestore and implement a sliding window to control API costs. Add a live agent handoff that escalates the conversation when the bot cannot resolve the issue after three attempts.

Building an AI Customer Support Chatbot in FlutterFlow

An AI chatbot provides instant answers to common questions, reducing support load and improving user experience. This tutorial builds a chatbot powered by the OpenAI Chat Completions API with your business knowledge base as context, a polished chat UI with message bubbles, conversation persistence in Firestore, and a handoff mechanism to escalate to a live agent when the bot reaches its limits.

Prerequisites

  • A FlutterFlow project with Firebase authentication enabled
  • An OpenAI API key with access to the Chat Completions API
  • Cloud Functions enabled on the Firebase Blaze plan
  • Firestore database configured in your Firebase project

Step-by-step guide

1

Set up the Firestore schema for chat sessions and messages

Create a `chat_sessions` collection with fields: userId (String), status (String: active/escalated/resolved), createdAt (Timestamp), lastMessageAt (Timestamp), escalatedAt (Timestamp, optional), agentId (String, optional). Add a `messages` subcollection under each session with fields: role (String: user/assistant/system), content (String), timestamp (Timestamp). The role field matches OpenAI's message format directly, making it easy to pass conversation history to the API. Register both collections in FlutterFlow's Data panel.

Expected result: Chat sessions and messages collections are created with roles matching OpenAI's format for seamless API integration.

2

Build the chat UI with reversed ListView and styled message bubbles

Create a ChatBot page. Add a Column filling the full screen. The main area is a ListView bound to a Backend Query on the current session's messages subcollection ordered by timestamp ascending, with the ListView set to reverse: true (this keeps the latest message at the bottom). For each message, use a Conditional layout: if role is 'user', align the Container to the right with a blue background and white text. If role is 'assistant', align left with a grey background and dark text. Add padding, rounded corners (topLeft, topRight, and the opposite bottom corner), and the message text inside. Below the ListView, pin a Row at the bottom with a multiline TextField and a Send IconButton. Add a typing indicator: when waiting for the bot response, show three animated dots in a left-aligned Container.

Expected result: A chat interface with user messages on the right in blue and bot responses on the left in grey, with a text input and send button pinned at the bottom.

3

Create the Cloud Function that calls OpenAI with your knowledge base

Create a callable Cloud Function named chatWithBot. It receives the sessionId and the user's message text. The function: (1) reads the last 10 messages from the session's messages subcollection, (2) constructs the OpenAI messages array starting with a system prompt containing your support knowledge base (FAQ answers, policies, product info), (3) appends the conversation history and the new user message, (4) calls the OpenAI Chat Completions API with model 'gpt-4o-mini' (cost-effective for support), (5) saves both the user message and assistant response to the messages subcollection, (6) returns the assistant's response text. Store the OpenAI API key in Firebase Functions config, never in client code.

functions/index.js
1const functions = require('firebase-functions');
2const admin = require('firebase-admin');
3const OpenAI = require('openai');
4admin.initializeApp();
5
6const openai = new OpenAI({
7 apiKey: functions.config().openai.key,
8});
9
10const SYSTEM_PROMPT = `You are a helpful customer support assistant for [YourApp].
11Knowledge base:
12- Pricing: Free plan includes X. Pro plan is $Y/month.
13- Returns: 30-day return policy for unused items.
14- Shipping: Standard 5-7 days, Express 2-3 days.
15- Account: Users can reset passwords via Settings > Security.
16Rules:
17- Be concise and friendly.
18- If you cannot answer, say "Let me connect you with a support agent."
19- Never make up information not in the knowledge base.`;
20
21exports.chatWithBot = functions.https.onCall(async (data, context) => {
22 if (!context.auth) throw new functions.https.HttpsError(
23 'unauthenticated', 'Must be logged in');
24
25 const { sessionId, message } = data;
26 const db = admin.firestore();
27 const messagesRef = db
28 .collection(`chat_sessions/${sessionId}/messages`);
29
30 // Save user message
31 await messagesRef.add({
32 role: 'user',
33 content: message,
34 timestamp: admin.firestore.FieldValue.serverTimestamp(),
35 });
36
37 // Load last 10 messages for context window
38 const history = await messagesRef
39 .orderBy('timestamp', 'desc').limit(10).get();
40 const messages = [
41 { role: 'system', content: SYSTEM_PROMPT },
42 ...history.docs.reverse().map(d => ({
43 role: d.data().role,
44 content: d.data().content,
45 })),
46 ];
47
48 const completion = await openai.chat.completions.create({
49 model: 'gpt-4o-mini',
50 messages,
51 max_tokens: 300,
52 });
53
54 const reply = completion.choices[0].message.content;
55
56 // Save bot response
57 await messagesRef.add({
58 role: 'assistant',
59 content: reply,
60 timestamp: admin.firestore.FieldValue.serverTimestamp(),
61 });
62
63 // Update session timestamp
64 await db.collection('chat_sessions').doc(sessionId).update({
65 lastMessageAt: admin.firestore.FieldValue.serverTimestamp(),
66 });
67
68 return { reply };
69});

Expected result: The Cloud Function receives user messages, sends them to OpenAI with the knowledge base context and conversation history, and returns the bot's response.

4

Wire up the chat UI to the Cloud Function with typing indicator

On the Send button tap, create an Action Flow: (1) Read the TextField value and clear it immediately for better UX. (2) Set a Page State variable isTyping to true — this shows the three-dot typing indicator in the ListView. (3) Call the chatWithBot Cloud Function via an API Call action, passing sessionId and the message text. (4) On success, set isTyping to false. The real-time listener on the messages subcollection (Single Time Query OFF) will automatically display both the user message and bot response as they are written to Firestore. If the API call fails, show a SnackBar error and set isTyping to false. Also check: if the bot's response contains 'connect you with a support agent', automatically trigger the escalation flow.

Expected result: Sending a message shows the typing indicator, calls the Cloud Function, and displays both the user message and bot response in real time.

5

Implement live agent handoff when the bot cannot resolve the issue

Track a Page State variable failedAttempts (Integer, starts at 0). When the bot's response contains phrases like 'I cannot help with that' or 'connect you with an agent', increment failedAttempts. When failedAttempts reaches 3 (or the user taps an Escalate button), update the chat_sessions document: set status to 'escalated' and escalatedAt to now. Display a system message: 'You have been connected to a support agent. Please wait for a response.' On the admin side, create a SupportQueue page listing sessions where status == 'escalated', ordered by escalatedAt ascending. Agents can claim a session (set agentId), view the full conversation history including bot messages, and reply directly. Agent messages are saved with role 'assistant' but a separate agentId field to distinguish from bot messages.

Expected result: After three failed bot attempts or manual escalation, the conversation transfers to a live agent queue. Agents see the full history and can continue the conversation.

Complete working example

Cloud Function — AI Chatbot with Escalation
1// Cloud Function: AI Customer Support Chatbot
2const functions = require('firebase-functions');
3const admin = require('firebase-admin');
4const OpenAI = require('openai');
5admin.initializeApp();
6
7const openai = new OpenAI({
8 apiKey: functions.config().openai.key,
9});
10
11const SYSTEM_PROMPT = `You are a helpful customer support
12assistant for [YourApp]. Answer questions using ONLY the
13knowledge base below. If the answer is not in the knowledge
14base, respond with: "I'm not sure about that. Let me
15connect you with a support agent who can help."
16
17Knowledge Base:
18- Pricing: Free (basic features), Pro $25/mo (all features)
19- Returns: 30-day return policy, contact support@app.com
20- Shipping: Standard 5-7 days ($5), Express 2-3 days ($15)
21- Account: Reset password in Settings > Security > Change Password
22- Billing: Update card in Settings > Billing > Payment Method
23- Cancel: Settings > Subscription > Cancel (effective end of period)
24
25Tone: Friendly, concise, helpful. Use bullet points for lists.`;
26
27const SLIDING_WINDOW = 10; // Last N messages for context
28
29exports.chatWithBot = functions.https.onCall(async (data, ctx) => {
30 if (!ctx.auth) throw new functions.https.HttpsError(
31 'unauthenticated', 'Login required');
32
33 const { sessionId, message } = data;
34 const db = admin.firestore();
35 const sessionRef = db.collection('chat_sessions').doc(sessionId);
36 const msgsRef = sessionRef.collection('messages');
37
38 // Check session is not escalated
39 const session = await sessionRef.get();
40 if (session.data()?.status === 'escalated') {
41 return { reply: 'A support agent is handling your case.' };
42 }
43
44 // Save user message
45 const now = admin.firestore.FieldValue.serverTimestamp();
46 await msgsRef.add({ role: 'user', content: message, timestamp: now });
47
48 // Load conversation window
49 const snap = await msgsRef.orderBy('timestamp', 'desc')
50 .limit(SLIDING_WINDOW).get();
51 const apiMessages = [
52 { role: 'system', content: SYSTEM_PROMPT },
53 ...snap.docs.reverse().map(d => ({
54 role: d.data().role, content: d.data().content,
55 })),
56 ];
57
58 // Call OpenAI
59 const completion = await openai.chat.completions.create({
60 model: 'gpt-4o-mini',
61 messages: apiMessages,
62 max_tokens: 300,
63 temperature: 0.3, // Lower = more consistent support answers
64 });
65 const reply = completion.choices[0].message.content;
66
67 // Save bot response
68 await msgsRef.add({ role: 'assistant', content: reply, timestamp: now });
69 await sessionRef.update({ lastMessageAt: now });
70
71 // Auto-escalate if bot indicates it cannot help
72 if (reply.toLowerCase().includes('connect you with')) {
73 await sessionRef.update({ status: 'escalated', escalatedAt: now });
74 }
75
76 return { reply };
77});

Common mistakes when implementing a Chatbot for Customer Support in FlutterFlow

Why it's a problem: Sending the entire conversation history to OpenAI on every message

How to avoid: Implement a sliding window that sends only the last 10 messages plus the system prompt. Optionally, summarize earlier messages into a condensed context note.

Why it's a problem: Storing the OpenAI API key in FlutterFlow's API Call configuration

How to avoid: Store the API key in Firebase Functions config (firebase functions:config:set openai.key=YOUR_KEY). The Cloud Function accesses it server-side, and the key never reaches the client.

Why it's a problem: Not implementing any handoff mechanism to live agents

How to avoid: Track failed attempts and auto-escalate after 3 unresolved attempts. Also provide a manual Escalate to Agent button so users can request human help at any time.

Best practices

  • Use a detailed system prompt with your actual FAQ, policies, and product information for accurate responses
  • Implement a sliding window of the last 10 messages to control API costs while maintaining context
  • Set temperature to 0.3 or lower for support chatbots to get consistent, factual answers
  • Show a typing indicator while waiting for the API response to set user expectations
  • Clear the input TextField immediately on send for a snappier user experience
  • Auto-escalate to a live agent when the bot indicates it cannot help with the question
  • Store all messages in Firestore so agents can see the full conversation history when escalation occurs

Still stuck?

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

ChatGPT Prompt

I'm building a customer support chatbot in FlutterFlow. I need a Cloud Function that calls OpenAI's Chat Completions API with my support knowledge base as the system prompt, a sliding window of the last 10 messages for context, a chat UI with user/bot message bubbles, and automatic escalation to a live agent after 3 failed attempts. Show me the Cloud Function code and FlutterFlow page layout.

FlutterFlow Prompt

Create a chatbot page with a reversed ListView showing message bubbles (user on right in blue, bot on left in grey), a text input with send button pinned at the bottom, and a typing indicator that shows while waiting for a response.

Frequently asked questions

Which OpenAI model should I use for a support chatbot?

Use gpt-4o-mini for most support chatbots. It is fast, cost-effective, and handles FAQ-style queries well. Use gpt-4o for complex troubleshooting that requires deeper reasoning.

How do I update the chatbot's knowledge base without redeploying?

Store the knowledge base content in a Firestore document. The Cloud Function reads it on each request to construct the system prompt. Non-technical team members can edit the knowledge base document without touching code.

Can I use Dialogflow instead of OpenAI?

Yes. Create a Dialogflow CX agent with intents for your support topics. Call the Dialogflow API from a Cloud Function instead of OpenAI. Dialogflow offers more structured conversation design but less flexibility for open-ended questions.

How do I handle multiple languages in the chatbot?

OpenAI models support many languages natively. Add an instruction in the system prompt: 'Respond in the same language the user writes in.' For structured knowledge bases, maintain translations in Firestore and include the appropriate language version in the prompt.

What are the costs of running an OpenAI-powered chatbot?

With gpt-4o-mini at approximately $0.15 per million input tokens and $0.60 per million output tokens, a typical support conversation of 10 messages costs roughly $0.001-0.005. At 1,000 conversations per month, expect about $1-5 in API costs.

Can RapidDev help build an enterprise support chatbot?

Yes. RapidDev can implement multi-channel support (in-app, email, SMS), knowledge base management with auto-training, conversation analytics, CSAT surveys, agent dashboards, and integration with help desk tools like Zendesk or Freshdesk.

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.