Skip to main content
Flutter Basics – Complete Beginner to Advanced Guide
CHAPTER 24 Beginner

Firestore Database Basics

Updated: May 16, 2026
30 min read

# CHAPTER 24

Firestore Database Basics

1. Introduction

Firebase Auth stores the user's email, but it cannot store their bio, their profile picture URL, or their history of social media posts. For that, we need a cloud database. Cloud Firestore is Firebase's flagship, highly scalable NoSQL database. It keeps your data in sync across all client devices in real-time, even if the user goes offline. In this chapter, we will master Firestore Database Basics. We will understand the NoSQL architecture of Collections and Documents, and execute cloud-based CRUD (Create, Read, Update, Delete) operations using the cloudfirestore package.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Enable Cloud Firestore in the Firebase Console.
  • Understand the NoSQL architecture (Collections vs Documents).
  • Install the cloudfirestore package.
  • Write data to the cloud using .add() and .set().
  • Read and listen to real-time database updates using StreamBuilder.

3. Collections and Documents (NoSQL Architecture)

Unlike SQLite (which uses Tables and Rows), Firestore is a NoSQL document database.
  • Collection: A folder. (e.g., users, posts, products).
  • Document: A specific file inside that folder. It contains data formatted exactly like JSON (Key-Value pairs). (e.g., a file containing John's bio, age, and name).

*Rule: A Collection can only hold Documents. A Document can hold data fields, AND it can hold Sub-Collections (a folder inside a file).* Path example: users (Collection) -> johnid (Document) -> name: "John"

4. Setup and Initialization

  1. 1. In the Firebase Console, click Firestore Database -> Create Database.
  1. 2. Start in Test Mode (this allows you to read/write without complex security rules for the next 30 days). Choose a location close to you.
  1. 3. In your Flutter project, add: cloudfirestore: ^4.7.0.

5. CREATE: Writing Data to Firestore

You get an instance of the database, target a Collection, and pass a Dart Map (dictionary) to be saved!
dart
12345678910111213
import 'package:cloud_firestore/cloud_firestore.dart';

Future<void> addUser() async {
  CollectionReference users = FirebaseFirestore.instance.collection(&#039;users');

  // .add() automatically generates a random, unique ID for this document!
  await users.add({
    &#039;name': 'Alice',
    &#039;age': 25,
    &#039;isPro': true,
  });
  print("User added to Cloud Firestore!");
}

*(If you want to specify the ID manually, for example, using the Firebase Auth User ID, use .doc(uid).set({...}) instead of .add().)*

6. UPDATE and DELETE

Target the specific Document ID to modify or destroy it.
dart
1234567891011
// UPDATE: Change Alice's age to 26
Future<void> updateUser(String documentId) async {
  await FirebaseFirestore.instance.collection(&#039;users').doc(documentId).update({
    &#039;age': 26,
  });
}

// DELETE: Remove the document entirely
Future<void> deleteUser(String documentId) async {
  await FirebaseFirestore.instance.collection(&#039;users').doc(documentId).delete();
}

7. READ: Real-Time Data (StreamBuilder)

Firestore's greatest superpower is real-time syncing. You do not need to refresh the screen to see new data. We use a StreamBuilder to listen to the snapshots() of a collection. If a user adds a document from a different computer, your screen will update instantly!
dart
123456789101112131415161718192021222324252627282930313233343536
class UserListScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Real-Time Users")),
      // 1. StreamBuilder listens to the live Firestore pipe!
      body: StreamBuilder<QuerySnapshot>(
        stream: FirebaseFirestore.instance.collection(&#039;users').snapshots(),
        builder: (context, snapshot) {
          
          // 2. Handle loading state
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(child: CircularProgressIndicator());
          }

          // 3. Extract the list of documents
          final List<DocumentSnapshot> documents = snapshot.data!.docs;

          // 4. Build a ListView!
          return ListView.builder(
            itemCount: documents.length,
            itemBuilder: (context, index) {
              // Access the JSON data map from the document
              Map<String, dynamic> data = documents[index].data() as Map<String, dynamic>;
              
              return ListTile(
                title: Text(data[&#039;name']),
                subtitle: Text("Age: ${data[&#039;age']}"),
              );
            },
          );
        },
      ),
    );
  }
}

8. Visual Learning: The Firestore Tree

txt
123456789
[ /users ] (Collection)
     |
     |-- [ 9xH72... ] (Document auto-ID)
     |       |-- name: "Alice"
     |       |-- age: 25
     |
     |-- [ z3P81... ] (Document auto-ID)
             |-- name: "Bob"
             |-- age: 30

9. Common Mistakes

  • Typos in Collection Names: If you write .collection('user') instead of .collection('users'), Firestore will not throw an error. Because it is NoSQL, it assumes you wanted to create a brand new, empty collection named 'user'. Always double-check your spelling!

10. Best Practices

  • Security Rules: Test mode leaves your database open to hackers. Before launching your app, you must write Firestore Security Rules in the console to ensure that only authenticated users can read/write data, and ideally, only the data that belongs to their specific Auth ID.

11. Practice Exercises

  1. 1. What is the equivalent of an SQL "Table" and "Row" in a NoSQL Firestore architecture?
  1. 2. What method should you use if you want Firestore to generate a random, unique alphanumeric ID for your new document?

12. MCQs with Answers

Question 1

A developer wants to display a live chat feed. When a new message is added to the Firestore database, it must instantly appear on the user's screen without them pulling to refresh. Which widget and Firestore method combination is required?

Question 2

You have a users collection. You want to save a new user's profile data, but you want the Document ID to exactly match their unique Firebase Authentication ID (UID) instead of a random string. Which write pattern should you use?

13. Interview Questions

  • Q: Explain the structural hierarchy of Cloud Firestore regarding Collections and Documents. Why can't a Collection hold data fields directly?
  • Q: Contrast the usage of FutureBuilder with StreamBuilder when interacting with Firestore data. Provide a use case for each.
  • Q: Explain how NoSQL databases differ from traditional relational SQL databases regarding predefined schemas and strict data types across documents within the same collection.

14. FAQs

Q: Does Firestore work if the user loses cell service (offline)? A: Yes! The cloudfirestore package has offline persistence enabled by default. If a user adds a note while in a tunnel, it saves to a local cache, the UI updates instantly, and the package automatically syncs it to the cloud the moment cell service is restored!

15. Summary

In Chapter 24, our application became globally dynamic. We explored the NoSQL architecture of Cloud Firestore, organizing data into scalable Collections and JSON-like Documents. We executed cloud CRUD operations using the cloud
firestore package, utilizing .add() to generate unique IDs and .set() to assign manual ones. Finally, we brought our UI to life by attaching a StreamBuilder to a Firestore .snapshots() stream, creating a seamless, real-time data flow from Google's servers directly to the user's glass screen.

16. Next Chapter Recommendation

Our logic and data pipelines are complete, but our app feels a bit rigid. Let's add some visual flair. Proceed to Chapter 25: Flutter Animations and Transitions.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·