Build an AI-powered virtual assistant embedded in your FlutterFlow app that understands user context, answers questions, and triggers in-app actions. The assistant calls OpenAI or Claude API through a Cloud Function with a system prompt containing your app's features and the user's profile data. Parse structured action responses to navigate pages, open features, or create records. Store conversation history in Firestore and add proactive tips based on user behavior patterns.
Building a Context-Aware AI Assistant for Your FlutterFlow App
A virtual assistant goes beyond a simple FAQ chatbot. It knows who the user is, what they have done in the app, and can actually perform actions like navigating to a page or creating a record. This tutorial builds an AI assistant using OpenAI or Claude API that receives app context through a system prompt, responds conversationally, and triggers app actions through structured output parsing.
Prerequisites
- A FlutterFlow project with Firestore and authentication configured
- An OpenAI or Anthropic Claude API key stored in Cloud Function environment variables
- Cloud Functions environment configured for your project
- An existing app with at least 3-4 features the assistant can help with
Step-by-step guide
Design the data model for assistant conversations and context
Design the data model for assistant conversations and context
Create an assistant_sessions collection with fields: userId (String), messages (Array of Maps: {role: 'user'|'assistant', content: String, timestamp: Timestamp, action: Map nullable}), createdAt (Timestamp), lastMessageAt (Timestamp). The messages array stores the full conversation history. The action field on assistant messages is optional and contains structured data like {type: 'navigate', page: 'orders'} when the assistant triggers an app action. Also document the context you will pass: user displayName, subscription tier, last 5 orders or key records, and available app features list.
Expected result: Firestore has assistant_sessions storing conversation history with optional action metadata per assistant message.
Build the Cloud Function for AI-powered responses with app context
Build the Cloud Function for AI-powered responses with app context
Create a Cloud Function named assistantChat that receives userId and userMessage. It fetches the user's profile from Firestore (name, tier, recent activity). Constructs a system prompt including: the app's feature list with descriptions, the user's name and subscription tier, recent orders or records (summarized), and instructions to respond as a helpful assistant that can suggest actions formatted as JSON. Sends the conversation history plus new message to OpenAI or Claude API. Parses the response: if it contains an action JSON block, extract it separately. Returns the text response and optional action to the client.
1// Cloud Function: assistantChat2const functions = require('firebase-functions');3const admin = require('firebase-admin');4const OpenAI = require('openai');56const openai = new OpenAI({7 apiKey: process.env.OPENAI_API_KEY8});910exports.assistantChat = functions.https11 .onCall(async (data, context) => {12 const { userId, userMessage, sessionId } = data;13 const db = admin.firestore();14 // Fetch user context15 const user = (await db.doc(`users/${userId}`)16 .get()).data();17 const orders = await db.collection('orders')18 .where('userId', '==', userId)19 .orderBy('createdAt', 'desc').limit(5).get();20 const orderSummary = orders.docs.map(d => {21 const o = d.data();22 return `${o.productName} on ${o.createdAt23 .toDate().toLocaleDateString()}`;24 }).join(', ');25 // Fetch conversation history26 const session = sessionId27 ? (await db.doc(28 `assistant_sessions/${sessionId}`29 ).get()).data()30 : { messages: [] };31 const history = (session.messages || [])32 .map(m => ({ role: m.role, content: m.content }));33 const systemPrompt = `You are a helpful assistant34 for our app. User: ${user.displayName},35 tier: ${user.subscriptionTier}.36 Recent orders: ${orderSummary}.37 App features: Orders, Settings, Profile,38 Notifications, Support.39 If the user wants to navigate, include:40 {"action":{"type":"navigate","page":"pageName"}}41 at the end of your response.`;42 const completion = await openai.chat43 .completions.create({44 model: 'gpt-4o',45 messages: [46 { role: 'system', content: systemPrompt },47 ...history,48 { role: 'user', content: userMessage }49 ],50 max_tokens: 50051 });52 const reply = completion.choices[0]53 .message.content;54 // Parse action if present55 let action = null;56 const actionMatch = reply57 .match(/\{"action":\{.*?\}\}/s);58 if (actionMatch) {59 action = JSON.parse(actionMatch[0]).action;60 }61 const textReply = reply62 .replace(/\{"action":\{.*?\}\}/s, '').trim();63 // Save to session64 const msgs = [65 ...session.messages || [],66 { role: 'user', content: userMessage,67 timestamp: new Date() },68 { role: 'assistant', content: textReply,69 timestamp: new Date(), action }70 ];71 const ref = sessionId72 ? db.doc(`assistant_sessions/${sessionId}`)73 : db.collection('assistant_sessions').doc();74 await ref.set({75 userId, messages: msgs,76 lastMessageAt: admin.firestore77 .FieldValue.serverTimestamp()78 }, { merge: true });79 return { reply: textReply, action,80 sessionId: ref.id };81 });Expected result: Cloud Function sends user context plus conversation history to the AI API and returns a response with optional action metadata.
Build the assistant chat interface
Build the assistant chat interface
Create an AssistantPage or an assistant BottomSheet accessible via a floating action button on any page. The layout mirrors a chat: a ListView displaying conversation messages with different styling for user (right-aligned, primary color) and assistant (left-aligned, grey background with an assistant avatar icon). At the bottom, a TextField with a send IconButton. On send, call the assistantChat Cloud Function with the user's message and current sessionId (stored in Page State). Display a typing indicator (three animated dots) while waiting for the response. When the response arrives, add both messages to the display list.
Expected result: A chat-style interface where users type questions and receive AI-generated responses with assistant avatar styling.
Implement action parsing to trigger in-app navigation and features
Implement action parsing to trigger in-app navigation and features
When the Cloud Function returns an action object (e.g., {type: 'navigate', page: 'orders'}), parse it in the Action Flow after receiving the response. Use a conditional chain: if action.type equals 'navigate', execute a Navigate To action targeting the specified page. If action.type equals 'create', create a document in the specified collection. If action.type equals 'open_support', navigate to the support page. Display suggested action buttons below the assistant's message as tappable Containers (e.g., 'Go to Orders' button). This makes the assistant functional rather than just conversational.
Expected result: The assistant can trigger app actions like navigating to pages or creating records based on user requests.
Add proactive assistant suggestions based on user behavior
Add proactive assistant suggestions based on user behavior
Create a Cloud Function that analyzes user activity patterns daily. Check for specific conditions: user has not set up notifications (show tip about notifications), user has items in cart for over 24 hours (remind them), user has not used a feature they might benefit from. Store proactive tips in a user_tips subcollection: tip (String), ctaText (String), ctaAction (Map), dismissed (Boolean). On the app home page or in the assistant interface, display undismissed tips as a card above the chat input. Each tip has a text message, a call-to-action button, and a dismiss button. When the user acts on a tip, mark it as dismissed.
Expected result: The assistant proactively surfaces relevant tips and suggestions based on what the user has or has not done in the app.
Complete working example
1FIRESTORE DATA MODEL:2 assistant_sessions/{sessionId}3 userId: String4 messages: [5 {6 role: 'user' | 'assistant',7 content: String,8 timestamp: Timestamp,9 action: { type: 'navigate', page: 'orders' } (nullable)10 }11 ]12 createdAt: Timestamp13 lastMessageAt: Timestamp1415 user_tips/{tipId}16 userId: String17 tip: String ('You have not set up notifications yet')18 ctaText: String ('Set Up Now')19 ctaAction: { type: 'navigate', page: 'notification_settings' }20 dismissed: Boolean21 createdAt: Timestamp2223SYSTEM PROMPT TEMPLATE:24 You are a helpful assistant for [App Name].25 User: {displayName}, tier: {subscriptionTier}.26 Recent activity: {summarized recent records}.27 Available features: {feature list with descriptions}.28 If the user wants to take an action, include:29 {"action":{"type":"navigate","page":"pageName"}}30 at the end of your response.3132PAGE: AssistantPage (or BottomSheet)33 Page State: sessionId (String), messages (List)3435 WIDGET TREE:36 Column37 ├── Proactive Tip Card (if undismissed tips exist)38 │ Text (tip message)39 │ Row: CTA Button + Dismiss Button40 ├── Expanded41 │ └── ListView (messages)42 │ User: right-aligned, primary color bubble43 │ Assistant: left-aligned, grey bubble + avatar44 │ Action buttons below assistant messages45 ├── Typing Indicator (visible while loading)46 └── Row47 ├── Expanded TextField48 └── Send IconButton49 On Tap:50 1. Add user message to list51 2. Show typing indicator52 3. Call Cloud Function assistantChat53 4. Add assistant response to list54 5. If action returned → execute action5556ACTION TYPES:57 navigate: Navigate To specified page58 create: Create Document in specified collection59 open_support: Navigate to support page60 show_info: Display information dialogCommon mistakes when designing a Virtual Assistant Feature in FlutterFlow
Why it's a problem: Sending entire user data to the AI API on every message
How to avoid: Send only a summarized user context in the system prompt: name, tier, and a brief summary of the last 5 relevant records. Include specific data only when the question relates to it.
Why it's a problem: Not storing conversation history between sessions
How to avoid: Store the full conversation in Firestore assistant_sessions. On reopening, load the previous session's messages so the assistant retains context.
Why it's a problem: Letting the assistant hallucinate app features that do not exist
How to avoid: Explicitly list available features and pages in the system prompt. Add an instruction: 'Only reference features from the provided list. If the user asks about something not available, say it is not currently supported.'
Best practices
- Summarize user context in the system prompt rather than sending raw database records
- Explicitly list available app features in the system prompt to prevent hallucination
- Store conversation history in Firestore for session continuity
- Parse structured action outputs to make the assistant functional, not just conversational
- Add proactive tips based on user behavior patterns for engagement
- Show a typing indicator during API calls so users know the assistant is processing
- Rate limit assistant API calls to prevent abuse and control costs
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to build a virtual assistant feature in my FlutterFlow app that uses OpenAI API via Cloud Functions, includes user context in the system prompt, can trigger in-app navigation through structured action responses, stores conversation history, and proactively suggests tips based on user behavior. Show me the data model, Cloud Function, chat UI layout, and action parsing logic.
Create a chat-style page with a list view of message bubbles, a text field at the bottom with a send button, and a small card above the input area for proactive tip suggestions with an action button and dismiss button.
Frequently asked questions
Should I use OpenAI or Claude for the assistant?
Both work well. OpenAI GPT-4o is widely supported with extensive documentation. Claude excels at following system prompt instructions precisely. Choose based on your cost preference and response quality needs. The Cloud Function approach makes it easy to switch models later.
How much does the AI API cost per conversation?
With GPT-4o at approximately $2.50 per million input tokens, a typical 10-message conversation with user context costs about $0.01-$0.03. For Claude, pricing is similar. Set a per-user daily message limit to control costs.
Can the assistant create records or modify data in the app?
Yes. When the assistant's response includes an action of type 'create', your Cloud Function or client-side Action Flow creates the specified document. Always validate the action before executing to prevent unintended data modifications.
How do I prevent the assistant from giving wrong information about my app?
List all features and their capabilities explicitly in the system prompt. Instruct the model to only reference listed features. Test with edge cases and refine the prompt. Add a disclaimer that the assistant may occasionally be inaccurate.
Can the assistant support voice input?
Yes. Add a microphone button next to the text field that uses speech-to-text to transcribe the user's voice, then send the transcribed text to the assistant Cloud Function. The response can optionally be read aloud using text-to-speech.
Can RapidDev help build a custom AI assistant for my app?
Yes. RapidDev can implement AI assistants with advanced context management, multi-step action workflows, voice integration, analytics on assistant usage, and fine-tuned models for your specific domain.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation