# How to Set Up a Live Chat Feature Using FlutterFlow

- Tool: FlutterFlow
- Difficulty: Beginner
- Time required: 30-40 min
- Compatibility: FlutterFlow Free+
- Last updated: March 2026

## TL;DR

Build a customer support live chat with a floating action button that opens a chat Bottom Sheet for users and a separate agent dashboard for support staff. Store support_chats with status tracking (waiting, active, resolved) and a messages subcollection for real-time messaging. Users send messages via a TextField pinned at the bottom. Agents see a queue of waiting chats, claim one to begin responding, and use canned response quick-reply buttons for common answers. A Cloud Function auto-assigns chats to available agents when no agent claims within 30 seconds.

## Building Customer Support Live Chat in FlutterFlow

Live chat connects app users with human support agents in real-time. Unlike peer-to-peer messaging, live chat requires queue management, agent assignment, and resolution tracking. This tutorial builds both the user-facing chat widget and the agent-side dashboard with claim system, canned responses, and chat resolution workflow.

## Before you start

- A FlutterFlow project with Firestore and Firebase Authentication configured
- A users collection with a role field to distinguish agents from regular users
- Basic familiarity with FlutterFlow Bottom Sheets, ListViews, and real-time Backend Queries

## Step-by-step guide

### 1. Set up the Firestore data model for support chats and messages

Create a support_chats collection with fields: userId (String), agentId (String, nullable), status (String: 'waiting', 'active', 'resolved'), subject (String), createdAt (Timestamp), resolvedAt (Timestamp, nullable), lastMessageAt (Timestamp). Create a support_chats/{chatId}/messages subcollection with: senderId (String), text (String), timestamp (Timestamp), isAgent (Boolean). Create a canned_responses collection with: text (String), category (String: 'greeting', 'troubleshooting', 'closing'), shortcut (String), order (Integer). This model separates the chat lifecycle (status) from the messages for clean queue management.

**Expected result:** Firestore has support_chats with messages subcollection and canned_responses ready for live chat.

### 2. Build the user-facing chat widget with FloatingActionButton trigger

On your main app pages, add a FloatingActionButton with a chat bubble Icon in the bottom-right corner. Show a Badge with unread message count using a Backend Query counting messages where isAgent == true and timestamp > lastReadTimestamp. On FAB tap, check if the user has an existing support_chats document with status 'waiting' or 'active'. If yes, open the existing chat. If no, create a new support_chats document with status 'waiting' and open it. The chat opens as a Bottom Sheet with a Column: header Row (subject Text + close IconButton), messages ListView (real-time Backend Query on messages subcollection ordered by timestamp ascending), and an input Row at the bottom with TextField and send IconButton.

**Expected result:** Users tap a floating chat button to start or resume a support conversation in a Bottom Sheet.

### 3. Create the agent dashboard with chat queue and claim system

Create an AgentDashboardPage (Conditional Visibility: user role == 'agent'). Add two tabs: Queue and My Chats. The Queue tab shows a ListView with Backend Query on support_chats where status == 'waiting', ordered by createdAt ascending. Each row shows: user avatar, subject, waiting time (calculated from createdAt), and an 'Accept' Button. On Accept tap: update the chat document agentId to currentUser.uid and status to 'active'. This removes it from other agents' queues. The My Chats tab shows a ListView filtered by agentId == currentUser.uid AND status == 'active'. Tap a chat to open the agent-side chat view.

**Expected result:** Agents see a queue of waiting chats and can claim them. Claimed chats move to the agent's active list.

### 4. Implement the agent chat view with canned responses

Create an AgentChatPage with Route Parameter chatId. Display the same message ListView as the user view but with agent-specific additions. Above the input Row, add a horizontal ScrollView of canned response Containers from a Backend Query on canned_responses ordered by order. Each Container shows the shortcut text. On tap, insert the canned response text into the TextField. Below the canned responses, add the standard input Row: TextField and send IconButton. On send, create a message document with isAgent: true. Add a 'Resolve' Button in the header that updates the chat status to 'resolved', sets resolvedAt to now, and sends a closing message.

**Expected result:** Agents can reply using canned responses or custom messages and resolve chats when complete.

### 5. Add auto-assignment and real-time status updates

Create a Cloud Function autoAssignChat triggered on support_chats document creation (status == 'waiting'). After a 30-second delay (Cloud Tasks or scheduled), check if the chat still has status 'waiting' (no agent claimed it). If so, query users where role == 'agent' and find the one with the fewest active chats (least busy), then assign agentId and set status to 'active'. On the user side, show status indicators: 'Waiting for agent...' Text with a loading animation when status == 'waiting', and 'Connected to [agentName]' when status == 'active'. Use a real-time listener on the support_chats document to update the status display instantly.

**Expected result:** Unclaimed chats are auto-assigned to the least busy agent, and users see real-time status updates.

## Complete code example

File: `FlutterFlow Live Chat Setup`

```text
FIRESTORE DATA MODEL:
  support_chats/{chatId}
    userId: String
    agentId: String (nullable)
    status: "waiting" | "active" | "resolved"
    subject: String
    createdAt: Timestamp
    resolvedAt: Timestamp (nullable)
    lastMessageAt: Timestamp
    └── messages/{messageId}
          senderId: String
          text: String
          timestamp: Timestamp
          isAgent: Boolean

  canned_responses/{docId}
    text: String
    category: "greeting" | "troubleshooting" | "closing"
    shortcut: String
    order: Integer

USER SIDE:
  FloatingActionButton (chat icon, bottom-right)
    Badge: unread agent message count
    On Tap:
      → Check existing chat (waiting/active)
      → If none: Create support_chats doc (status: waiting)
      → Open ChatSheet Bottom Sheet

  ChatSheet:
    Column
      ├── Row (subject + status indicator + close)
      ├── Text ("Waiting..." if status == waiting)
      ├── ListView (messages, real-time, ordered timestamp)
      │     isAgent true → left aligned, grey bg
      │     isAgent false → right aligned, primary bg
      └── Row (TextField + send IconButton)

AGENT SIDE:
  AgentDashboardPage (role == 'agent' only)
    TabBar: Queue | My Chats
    Queue Tab:
      ListView (support_chats, status == waiting, oldest first)
        Row: avatar + subject + wait time + Accept Button
        Accept: set agentId, status = 'active'
    My Chats Tab:
      ListView (support_chats, agentId == me, status == active)

  AgentChatPage:
    Column
      ├── Row (user info + Resolve Button)
      ├── ListView (messages, real-time)
      ├── ScrollView.horizontal (canned responses)
      └── Row (TextField + send IconButton)
```

## Common mistakes

- **No agent claim system causing multiple agents to respond to the same chat** — Without a claim mechanism, all agents see all waiting chats and multiple agents may start responding simultaneously, confusing the user. Fix: Implement a claim system: the Accept button atomically sets agentId and changes status to 'active', immediately removing the chat from other agents' queues.
- **Using a Single Time Query instead of real-time for the message list** — Messages from the other party do not appear until the page is refreshed. Live chat must be real-time to function properly. Fix: Disable Single Time Query on the messages Backend Query so it uses a real-time Firestore listener. New messages appear instantly.
- **Not showing the chat status to the user while waiting for an agent** — Users send a message and see nothing happen. They do not know if anyone received it, leading to frustration and duplicate chat requests. Fix: Show a clear status indicator: 'Waiting for an agent...' with a loading animation when status is waiting, and 'Connected to [name]' when an agent accepts.

## Best practices

- Use a claim system where agents explicitly accept chats to prevent duplicate responses
- Enable real-time Firestore listeners for instant message delivery on both sides
- Show clear status indicators (waiting, connected, resolved) to keep users informed
- Pre-populate canned responses for common questions to speed up agent response time
- Auto-assign unclaimed chats after a timeout to prevent users waiting indefinitely
- Track resolution time (resolvedAt - createdAt) for agent performance metrics
- Add a satisfaction rating prompt after chat resolution for quality monitoring

## Frequently asked questions

### Can I add a chatbot that handles common questions before connecting to an agent?

Yes. Add an initial automated flow where the bot asks the user's question category and checks against a FAQ database. If no match, create the support_chats document with status 'waiting' to route to a human agent.

### How do I handle multiple simultaneous chats per agent?

On the My Chats tab, the agent sees all their active chats in a list. They can switch between chats by tapping each one. Set a maximum concurrent chat limit (e.g., 5) in the auto-assignment Cloud Function to prevent agent overload.

### Can I add file and image sharing in the chat?

Yes. Add a type field to messages (text, image, file). Include an attachment IconButton next to the TextField. Use FlutterFlowUploadButton to upload to Firebase Storage and save the download URL in the message document.

### How do I send push notifications when a new message arrives?

Create a Cloud Function triggered on message creation in the messages subcollection. Look up the recipient (agent or user) FCM token and send a push notification with the message preview.

### Can I track agent response time and performance?

Yes. Calculate first response time (first agent message timestamp minus chat createdAt), average response time between messages, and resolution time (resolvedAt minus createdAt). Display these metrics on an admin analytics page.

### Can RapidDev help build a complete customer support system?

Yes. RapidDev can implement a full support system including live chat, chatbot automation, ticket management, agent analytics, customer satisfaction surveys, and integration with tools like Zendesk or Intercom.

---

Source: https://www.rapidevelopers.com/flutterflow-tutorials/how-to-set-up-a-live-chat-feature-using-flutterflow
© RapidDev — https://www.rapidevelopers.com/flutterflow-tutorials/how-to-set-up-a-live-chat-feature-using-flutterflow
