How to make flutterflow quiz app step by step
In today’s How-To_Series, we will explore how to create a quiz application using FlutterFlow with no code. this guide will walk you through every step, from concept to completion. Let’s dive in
Phase 1 : Setting Up the Project in FlutterFlow and building the User Interface
Template selection
We need to focus on building the functionality and so we will use an existing template for the user interface of the quiz application.
- Navigate to the FlutterFlow marketplace from your FlutterFlow dashboard and Select the “Quiz Template by Flutterflow”, which is free and contains pre-built elements for a quiz application.


Creating the Project in FlutterFlow
- After selecting the template, click on “Create Project”.
- The project will clone all necessary features and elements from the template into your FlutterFlow project.
Overview of the Project Pages
We will take a look at the different pages included in the template and decide which ones to keep or modify. (Do this according to the features you require for your quiz app)
The template includes several pages such as confetti winner page, game page, leaderboard, select level, settings, and profile.
We will focus on necessary pages for this tutorial and remove unnecessary pages to match our project requirements. (We will leave the ConfettiWinnerPage, GamePage and the SelectLevel page)
Customizing the User Interface
Customizing the UI by removing unnecessary elements/ pages and simplifying the design. In this example after we worked on the user interface we simplified the design to look like this.
Select level page

Game page
Confetti winner page
Phase 2 : Setting Up Firebase
Now we can start building the backend to store and manage data for our quiz application. We will focus on creating the necessary collections we need for firebase to store our data and we will start by Identifying the main features needed for the quiz app.
- user authentication
- A list of quizzes for the user to select with at least 10 questions each with options, correct answers, quiz progress tracker and a score tracker.
Using ChatGPT, we can quickly generate the necessary collection structure for our quiz app and once we have our simple collection structure we can set up our firebase project on flutterflow.
Collection 1: Users
This collection stores all the details about users.
Fields:
– `email` (String): The user’s email address.
– `display_name` (String): The name displayed for the user.
– `photo_url` (Image): URL to the user’s profile photo.
– `uid` (String): Unique identifier for the user.
– `created_time` (DateTime): The time the user account was created.
– `phone_number` (String): The user’s phone number.
– `last_active_time` (DateTime): The last time the user was active.
– `role` (String): The role of the user (e.g., admin, participant).
– `title` (String): User’s title or status.
– `quizList` (List<Doc Reference<Quiz>>): A list of quizzes associated with the user.
Collection 2: Quiz
This collection holds information about each quiz.
Fields:
– `title` (String): The title of the quiz.
– `description` (String): A brief description of the quiz.
– `createdAt` (DateTime): The date and time the quiz was created.
– `numberOfQuestions` (Integer): The total number of questions in the quiz.
Collection 3: Questions
This collection contains the questions for the quizzes.
Fields:
– `parentQuiz` (Doc Reference<Quiz>): Reference to the quiz this question belongs to.
– `questionText` (String): The text of the question.
– `options` (List<String>): List of possible answers.
– `correctOption` (String): The correct answer.
– `order` (Integer): The order of the question in the quiz.
– `usersResponded` (List<Doc Reference<Users>>): Users who responded to the question.
Collection 4: UserProgress
This collection tracks the progress of users in quizzes.
Fields:
– `userld` (Doc Reference<Users>): Reference to the user.
– `quizld` (Doc Reference<Quiz>): Reference to the quiz.
– `progress` (List<Doc Reference<Questions>>): List of questions answered or in progress.
Collection 5: UserAnswers
This collection records the answers provided by users.
Fields:
– `quizld` (Doc Reference<Quiz>): Reference to the quiz.
– `questionld` (Doc Reference<Questions>): Reference to the question.
– `optionSelected` (String): The option selected by the user.
– `answeredCorrectly` (Boolean): Whether the selected option was correct.
– `userld` (Doc Reference<Users>): Reference to the user.
Note: Firebase is a NoSQL database, which means you can use any kind of structure to store your data for a quiz app. With NoSQL, you have the flexibility to store data in formats like JSON, allowing you to easily manage questions, answers, user scores, and other dynamic elements without being restricted to a fixed schema.
The collection structure above is just an example, but when you understand collections and data fields structure, there is no strict rule to follow, and my example structure above is not the one you must always follow.
Setting up the collections and data fields in flutterflow
- Head over to the settings tab on your flutterflow project
- Click “create project” then follow all the on screen prompts to create your firebase project.

- Click on the firestore (1) tab then the plus button (2) to create new collections and add the data fields to the collections based on your defined schema (3)
Phase 3 : Setting Up Data Queries
Now let’s set up data queries in FlutterFlow and add functionality to all the pages. Firstly we will need to set up authentication on flutterflow and add authentication pages, we will use a template from flutterflow for this to simplify the process.
- Click on the plus sign to add a new project page to the project
- Then click on the flows tab and select the account and profile creation flow to “add to project”. You can customize the
You can customize the flow by adding or removing or adding any feature or element that suits your own project. After adding the authentication flow we have to set the entry page for the app when users are logged in vs when they aren’t.
- Click on the settings tab, then click on “Authentication” and make sure that authentication is enabled.
- Make sure that firebase is selected as the authentication method of choice and finally you can set the entry page and logged in page from your list of pages.
The entry page in this project is the ‘auth_2_Create’ page from the authentication flow and the logged in page is the ‘selectLevel’.
Now we will move to the SelectLevel page and you can click the listview widget holding the quiz cards and clear any previous queries.
- Query the quizzes collection and order them by the creation date.
Next we need to work on the progress tracker feature so a user can see their progress in each quiz. We’ll use the “user progress” collection and query the data on the progress bar.
We’ll filter the user progress ‘quizid’ by the quiz reference in the list query and the ‘userId’ by the authenticated user reference.

Next we need to use the ‘numberOfQuestions’ integer from the quizDocument in the listview query to divide against the number of questions answered to return a double value from 0, 0.1, 0.2… to 1 because the progress bar widget will only accept the value within that range.
We will need to use a custom function to create this logic.
This function will:
• Take the number of questions answered and the total number of questions as inputs and then divide it.
• Return a double representing the progress.
Note: A custom function is how you can create your own custom logic in Flutter Flow that can make manipulations within the variable. With custom functions in Flutter Flow, you can manipulate variables and their output. This means you can input data from your application, perform calculations, and build any kind of logic you need. For more details, you can refer to the Flutter Flow documentation.
Let’s create a custom function in flutterflow.
- Head over to the custom functions tab
- Click on the add button
- Define the type of argument variables that the function will need to make the calculation. For this function we need integers, one for the number of questions answered and the question number.
- Define the return output expected and give the function a name. For this function the expected return value is ‘double’ and the name of the function is ‘calculateProgress’
- Move to the code co-pilot section and prompt it to create the custom function code. For this function the prompt used is ‘return a double value from 0 to 1 based on the answered count divided by the questions number’

After the function has been created
- Head over to the selectLevel page, click on the progress value widget
- Click on the orange icon in the progress value properties and select the custom function that you just created.
- Set the function arguments; (1) the number of questions answered will come from the user progress document on the progress bar query, progress number of document reference <question> list. (2) The number of questions will come from the numberOfQuestions integer in the quiz document from the listview query.
We need to add an action on the container widget to direct users to the Gamepage so the user can play the specific quiz they’ve clicked on and to do that we will need to add parameters to the GamePage so we can send the document reference of the specific quiz clicked and other relevant data. In this project I am also sending the number or quiz questions to the GamePage.

On the Select level page we will add the action to the container to direct users to the Gamepage but let’s discuss some logic here, we need users to have a user progress document for each quiz but only one document and so we need to have a way to know if a quiz already has a progress document attached to it.


- Add a conditional action to check the authenticated users quizList if the list contains the current quizItem reference from the listView query.
- (if true) Then the user is clicking to replay a quiz that already has a userProgress document attached to it and so we can add a navigate action to the Gamepage.
- (if false) Then the user is clicking a new quiz without a userProgress and so we can add three actions, updating the auth users document with the current quizItem reference from the listView query, creating a new user progress document with the ‘userId’ the current auth users reference and the quizId the current quizItem reference from the list view query, the final argument will be a navigation action to the GamePage.
Now on the GamePage we will start with adding a pageview at the base of the column holding the question and the options.

We will leave only one pageview page and delete the others. We’ll use a Page View widget to create a slideshow-like experience for the quiz. This allows us to present each question on a separate page and navigate through them.
- Click on the pageview widget and head over to the properties tab on the right and then disable the ‘show indicator’ and the ‘allow swipe scrolling’

Following the widget structure above we need to make two queries, (1) One query is to the userAnswer collection to make sure that every question that the user has submitted an answer to is recorded (list of documents query). (2) The second query is to the Questions collection to display all the questions set for that particular quiz (list of documents query).
To achieve both queries, in the widget structure two containers are layered on each other before the base of the pageview widget. Each container has its respective queries

The User answers query is filtered by the quizId from the page parameter and the current user Authentication reference.
The Questions read collection is filtered by the parent quiz which is from the quizId parameter and then we are ordering the documents with the order int field in increasing order. The intention is that every question will have an order number 1, 2, 3 etc and this query will display the questions in that number.
- Click the pageview and then on the right tab select the set from the variables tab to access the questions read in the above container.
- Make sure you give the variable a name. In the example above we used the name ‘’QuestionList’’
Note: The set from the variable tab allows you to inherit data on parent widget from another query above.
The Next step is accessing the variables like the question Title, question number and options from each question item on the ‘QuestionList’ variable. Use the information from the questionList item to populate the data to display data from each question.


Even the options will be set from variable questionList options list <string>
We are almost done with the functionality of the Gamepage and the last function is the action that will be triggered once a user clicks on an option.

Click on the options button and move to the actions tab. The previous actions have been deleted but in this project we left the widget animation and then the haptic feedback action for a light vibration once the user taps the option.
Let’s describe the logic we want to attach to the options button and the actions needed to achieve that logic.
1. Update User Progress: When the options button is pressed, we want to update the user progress document. We’ll add the current question reference from the questionList variable to the progress list in the user progress document. This helps us track the number of questions answered. Using a list of question references ensures uniqueness because Firebase won’t allow duplicate entries.
2. Store User Answers: The Answer query we configured earlier helps store the questions the user has answered. We need a condition to check if a user has answered a question:
• If the user hasn’t answered the question, create a new userAnswer document.
• If the user has answered the question before, update the existing answer document with the user’s current selection.
3. Track Responded Users: The usersResponded list in the questions document (from questionList query) collects the references of users who have answered a question. This helps us manage and update user responses accurately. We can set a conditional action to check if the current auth user is in the userResponded list.
The condition action will return true or false actions.
Responded users conditional action (on True)

Action One: Correct Option Conditional Action: We will set up a conditional action to check if the option clicked by the user matches the correct option (a string) from the question document in the questionList. This will return a true or false result.
Correct option condition (On True) : Following the responded users conditional action (true) we know that in this part of the flow the usersAnswer document for this question already exists and so we will choose the update document action and use the userAnswer ref from the userAnswer document list (from the container Query) choosing the filter by items option then select the item in list Questionid equal to the current questionList ref; We will update the option selected string with the current option selected (string) and the answeredCorrected bool to true (because the correct option condition is true)


Next we need to know if the user is on the last question and then we can navigate the user to the confettiWinnerPage and if false we will add an action to navigate the pageview to the next question.
To carry out this logic we will add another conditional action (if questionList item’s order is equal to parameter: numberOfQuestions)
(on True)
- Add a navigate action to the ‘conffetiWinnerpage’
(on False)
- Move the pageView to the next question.
Correct option condition (On False) : We will follow the same actions on the Correct option condition (on True) condition but the updated userAnswer document will have the answeredCorrectly bool to false.
Responded users conditional action (on False): We will follow all the actions on the Correct option condition (On True) but after Correct option condition on both (true) and (false) after the update document action for the userAnswer document we will add another update document action to update the questionList item ref – userResponded list with the current auth user’s reference.
Moving on to the last page, on the confettiWinnerPage we want to show the total score of the user [number of questions answered correctly] / [number of quiz questions]. We can define these two parameters on the confettiWinnerPage and pass it from the previous action that navigates to the confettiWinnerPage.
Then display on the page ui. The number of questions passed from the navigation action on the gamePage will come from the numberOfQuestions parameter and the totalScore will come from the userAnswers document list – filtered list items by the answeredCorrectly equal to true – Number of items.
Conclusion
Now you have a functional quiz app! You can run tests on FlutterFlow to see it in action. Feel free to explore more by adding extra features or modifying the project to suit your needs.