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

How to Create a Custom Survey Widget for Your FlutterFlow App

Build a multi-question survey with different question types — text input, single-select radio buttons, multi-select checkboxes, star rating, and scale slider. Store survey structure in a Firestore questions subcollection with a questionType field. Render each question dynamically using Conditional Builder based on type. Collect responses in a Page State Map and submit to a survey_responses collection. Show a progress indicator and validate required questions before advancing.

What you'll learn

  • How to design a Firestore data model for multi-type survey questions
  • How to render different input widgets per question type using Conditional Builder
  • How to collect and validate responses in a Page State Map
  • How to submit survey responses to Firestore with user and timestamp data
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read25-30 minFlutterFlow Free+March 2026RapidDev Engineering Team
TL;DR

Build a multi-question survey with different question types — text input, single-select radio buttons, multi-select checkboxes, star rating, and scale slider. Store survey structure in a Firestore questions subcollection with a questionType field. Render each question dynamically using Conditional Builder based on type. Collect responses in a Page State Map and submit to a survey_responses collection. Show a progress indicator and validate required questions before advancing.

Building a Multi-Type Survey in FlutterFlow

Surveys need different question types for different data. Unlike a quiz with only multiple choice, surveys use text fields, dropdowns, checkboxes, ratings, and scales. This tutorial builds a flexible survey system that renders questions dynamically from Firestore and handles all common question types.

Prerequisites

  • A FlutterFlow project with Firestore configured
  • A surveys collection and questions subcollection in Firestore
  • Understanding of Conditional Builder and Page State in FlutterFlow

Step-by-step guide

1

Create the Firestore data model with typed question documents

Create a surveys collection with fields: title (String), description (String). Create a questions subcollection with fields: questionText (String), questionType (String enum: text, radio, checkbox, rating, slider), options (String Array, for radio/checkbox types), isRequired (Boolean), order (int), placeholder (String, for text type). Add 5-6 test questions with different types to verify rendering.

Expected result: Firestore has a surveys collection with a questions subcollection containing various question types.

2

Build the survey page with PageView and dynamic question rendering

Create a SurveyPage with Route Parameter surveyId. Add a Backend Query for the questions subcollection ordered by the order field. Add a PageView with page snapping and disabled swiping (NeverScrollableScrollPhysics). For each question page, add a Conditional Builder that checks questionType: if 'text' → render TextField, if 'radio' → render RadioButtonGroup with options, if 'checkbox' → render CheckboxGroup, if 'rating' → render a star rating Row, if 'slider' → render Slider.

Expected result: Each survey question page renders the appropriate input widget based on questionType.

3

Collect responses in a Page State Map keyed by question ID

Add a Page State variable called responses (JSON type). On each input widget's On Changed action, update the responses Map: set the key as the question document ID and the value as the answer (string for text, selected option index for radio, list for checkbox, number for rating/slider). This collects all responses in one structured object. Access via responses[questionId] to check if a specific question has been answered.

Expected result: The responses Map accumulates answers as the user progresses through questions.

4

Validate required questions and show progress

Add a LinearPercentIndicator at the top bound to currentIndex / totalQuestions. On the Next button tap, check if the current question has isRequired true and if responses[currentQuestionId] is empty. If required and empty, show a Snackbar error 'This question is required.' and block navigation. If answered or not required, animate to the next page. On the last page, change button text to 'Submit'.

Expected result: Required questions block advancement until answered, and progress updates with each completed question.

5

Submit responses to Firestore and show a thank-you screen

On Submit button tap, create a document in survey_responses collection with fields: surveyId, userId (current user or anonymous device ID), responses (the Map), submittedAt (timestamp). Navigate to a thank-you page or show a success dialog. Optionally trigger a Cloud Function on new response documents to send a Slack notification or aggregate results.

Expected result: Survey responses are saved to Firestore with user identification and timestamps.

Complete working example

FlutterFlow Survey Setup
1FIRESTORE DATA MODEL:
2 surveys/{surveyId}
3 title: String
4 description: String
5 questions/{questionId}
6 questionText: String
7 questionType: "text" | "radio" | "checkbox" | "rating" | "slider"
8 options: ["Option A", "Option B", "Option C"] (radio/checkbox only)
9 isRequired: Boolean
10 order: int
11 placeholder: String (text only)
12
13PAGE STATE:
14 currentIndex: int = 0
15 responses: JSON Map = {}
16
17WIDGET TREE:
18 Column
19 LinearPercentIndicator (percent: currentIndex / total)
20 Expanded
21 PageView (horizontal, NeverScrollableScrollPhysics)
22 Per question:
23 Column
24 Text (questionText, Headline Small)
25 SizedBox (20)
26 Conditional Builder (questionType)
27 "text" TextField (maxLines: 3, placeholder)
28 "radio" RadioButtonGroup (options)
29 "checkbox" CheckboxGroup (options)
30 "rating" Row of 5 Star Icons
31 "slider" Slider (min 1, max 10)
32 Button ("Next" / "Submit")
33 On Tap:
34 1. If isRequired && !responses.has(questionId) Show Error Snackbar
35 2. Else if not last Animate Next Page + increment currentIndex
36 3. Else Create Document survey_responses Thank You
37
38SURVEY RESPONSES DOCUMENT:
39 surveyId: String
40 userId: String
41 responses: { "questionId1": "answer", "questionId2": 4, ... }
42 submittedAt: Timestamp

Common mistakes when creating a Custom Survey Widget for Your FlutterFlow App

Why it's a problem: Not validating required questions before allowing navigation to the next question

How to avoid: Check the isRequired flag on each question. Block the Next button and show an error if a required question has no response.

Why it's a problem: Using App State instead of Page State for survey responses

How to avoid: Use Page State for in-progress survey data so responses reset when the user leaves the page.

Why it's a problem: Loading all question responses into a flat List instead of a keyed Map

How to avoid: Use a JSON Map with question document IDs as keys. This makes responses robust to question order changes.

Best practices

  • Use a Firestore data model with questionType field for flexible question rendering
  • Render inputs dynamically with Conditional Builder based on questionType
  • Collect responses in a keyed Map (questionId → answer) for reliable data
  • Validate required questions before allowing navigation
  • Show a progress indicator so respondents know how many questions remain
  • Store responses with surveyId and userId for analytics and filtering
  • Use Page State (not App State) for in-progress survey data to prevent stale responses

Still stuck?

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

ChatGPT Prompt

I want to build a multi-type survey in FlutterFlow with text, radio, checkbox, rating, and slider question types loaded from Firestore. Explain the data model, dynamic rendering with Conditional Builder, response collection in a Map, and submission to Firestore.

FlutterFlow Prompt

Create a page with a progress bar at top, a large question text area, an area below for the answer input (I will add different input types), and a Next button at the bottom.

Frequently asked questions

Can I add conditional logic (show question B only if question A answer is X)?

Yes but it requires custom logic. Add a showIf field to question documents with a condition (dependsOnQuestionId, expectedValue). Check this in the rendering logic with Conditional Visibility.

How do I analyze survey results?

Query the survey_responses collection and aggregate responses per question. Use a Cloud Function to compute averages, counts, and percentages, or export to a spreadsheet.

Can I create anonymous surveys without user login?

Yes. Skip the userId field or use a device identifier from Global Properties. Set Firestore security rules to allow anonymous writes to survey_responses.

How do I prevent duplicate survey submissions?

On page load, query survey_responses for the current userId + surveyId. If a document exists, redirect to a 'You already completed this survey' page.

Can I add an image to survey questions?

Yes. Add an imageUrl field to question documents. Display an Image widget above the question text with Conditional Visibility for when imageUrl is not empty.

Can RapidDev help build a survey platform?

Yes. RapidDev can build survey platforms with conditional logic, branching paths, result dashboards, export features, and multi-language support.

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.