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

What Data Types Can Be Stored in a FlutterFlow Database?

FlutterFlow's Firestore database supports ten data types: String, Integer, Double, Boolean, Timestamp, GeoPoint, DocumentReference, Array, Map, and Null. Choose types carefully — storing prices as String instead of Double prevents range queries. Timestamps must be used for dates. DocumentReference creates relationships between documents. Arrays and Maps store structured nested data. Supabase (PostgreSQL) is available as an alternative for complex relational data with SQL types.

What you'll learn

  • What each Firestore data type is used for and when to choose it over alternatives
  • How FlutterFlow's field type selector maps to widgets and query operators
  • Common type mistakes that break queries, sorting, and arithmetic operations
  • How Supabase PostgreSQL types compare to Firestore types for relational data needs
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate10 min read20-30 minFlutterFlow Free+ with Firebase Firestore or SupabaseMarch 2026RapidDev Engineering Team
TL;DR

FlutterFlow's Firestore database supports ten data types: String, Integer, Double, Boolean, Timestamp, GeoPoint, DocumentReference, Array, Map, and Null. Choose types carefully — storing prices as String instead of Double prevents range queries. Timestamps must be used for dates. DocumentReference creates relationships between documents. Arrays and Maps store structured nested data. Supabase (PostgreSQL) is available as an alternative for complex relational data with SQL types.

Choosing the right data type is the foundation of a reliable FlutterFlow app

Every field in your FlutterFlow Firestore database has a type. The type determines what values the field can store, how it can be queried and sorted, and which FlutterFlow widgets can bind to it. Choosing the wrong type creates subtle bugs: storing a price as String means you cannot query for products under $50. Storing a date as String means you cannot sort by date or use date arithmetic. This guide covers every data type available in FlutterFlow's Firestore panel, when to use each, what widget it maps to, and the most common mistakes to avoid. It also compares Firestore types to Supabase PostgreSQL types for developers considering the relational database option.

Prerequisites

  • FlutterFlow project with Firebase Firestore enabled
  • Basic understanding of Firestore collections and documents in FlutterFlow
  • Access to FlutterFlow's Firestore panel for field type selection

Step-by-step guide

1

String, Integer, and Double — the basic scalar types

String stores text: names, email addresses, descriptions, status values ('active', 'pending', 'cancelled'), and URL strings. Maximum field size: 1MB (a single field), but keep fields under 1KB for performance. Integer stores whole numbers without decimal points: counts (likeCount, viewCount, quantity), ages, item counts, and sequential numbering. Supports range queries (count > 100), arithmetic, and ordering. Double stores decimal numbers: prices (29.99), coordinates (latitude: 37.7749), percentages (0.85), and measurements. IMPORTANT: always use Double for prices, never String. In FlutterFlow's Firestore panel, click the field type dropdown and select String, Integer, or Double when creating the field. String fields bind to Text widgets, Integer and Double bind to Text widgets with Custom Function formatting.

Expected result: Scalar fields are configured with appropriate types so range queries, arithmetic, and sorting work correctly.

2

Boolean and Timestamp — flags and dates

Boolean stores true/false values: isActive, isVerified, isPremium, hasCompletedOnboarding, isFeatured. In FlutterFlow, Boolean fields bind to Switch and Checkbox widgets. Use Boolean fields in Backend Query conditions for filtering (isActive == true). Timestamp stores date and time values in UTC. ALWAYS use Timestamp for any date-related field — not String, not Integer (Unix epoch is acceptable but less readable). Timestamps support range queries (createdAt > yesterday's timestamp), date arithmetic in Cloud Functions, and proper ordering. In FlutterFlow, Timestamp fields bind to DateTimePicker widgets and display via Custom Functions that format them as human-readable strings. Set the value using Current Date Time in action flows or FieldValue.serverTimestamp() for write-time precision.

timestamp_formatter.dart
1// Custom Function: formatTimestamp
2// Converts a Firestore Timestamp to a readable string
3// Parameters: timestamp (DateTime in FlutterFlow)
4String formatTimestamp(DateTime timestamp) {
5 final now = DateTime.now();
6 final diff = now.difference(timestamp);
7
8 if (diff.inMinutes < 1) return 'just now';
9 if (diff.inMinutes < 60)
10 return '${diff.inMinutes}m ago';
11 if (diff.inHours < 24)
12 return '${diff.inHours}h ago';
13 if (diff.inDays < 7)
14 return '${diff.inDays}d ago';
15
16 // Fallback to date string
17 return '${timestamp.day}/${timestamp.month}'
18 '/${timestamp.year}';
19}

Expected result: Date and flag fields use correct types enabling date-range queries, sorting, and proper widget binding.

3

GeoPoint and DocumentReference — location and relationships

GeoPoint stores a geographic coordinate as a latitude/longitude pair. Use it for user locations, store addresses, delivery points, and any map-related data. In FlutterFlow, GeoPoint fields provide latitude and longitude as separate Double values that you can use as inputs to FlutterFlowGoogleMap markers. Firestore does not support native geospatial queries (no 'find all points within 5km') — use the geoflutterfire2 package or the GeoHash pattern for proximity queries. DocumentReference stores a pointer (reference) to another Firestore document. This is how you create relationships between documents: an order document has a userId field of type DocumentReference pointing to the user document. In FlutterFlow, DocumentReference fields enable document lookup — you can fetch the referenced document in a Backend Query. Use DocumentReference for one-to-many relationships (order → user, comment → post).

Expected result: Location data uses GeoPoint type for map integration; related documents use DocumentReference for efficient lookups.

4

Array and Map — structured nested data

Array stores an ordered list of values, all of the same type: a list of tag strings, a list of UIDs for liked users, a list of product IDs in a wishlist. Firestore supports arrayContains and arrayContainsAny filter operators for arrays. Maximum array size: bounded by the 1MB document limit (avoid unbounded arrays, use subcollections for growing lists). In FlutterFlow, Array fields appear as List variables — iterate them with Generate Dynamic Children on a ListView. Map stores a nested object (key-value pairs) inside a document field: an address Map with street, city, state, zip keys; a metadata Map with version, source, processedAt keys. Map fields do not support direct querying in Firestore (you cannot WHERE address.city == 'NYC') — use top-level fields for frequently queried data. In FlutterFlow, access Map fields using field.key notation.

Expected result: Lists of values use Array type; nested structured data uses Map type with understanding of their query limitations.

5

Compare Firestore types to Supabase PostgreSQL types

If your app has complex relational needs, Supabase (PostgreSQL) is available as an alternative backend in FlutterFlow via Settings → Integrations → Supabase. PostgreSQL types map roughly as: TEXT (like String), INTEGER / BIGINT (like Integer), FLOAT8 / NUMERIC (like Double), BOOLEAN (like Boolean), TIMESTAMPTZ (like Timestamp with timezone), POINT (like GeoPoint but with native spatial queries via PostGIS), UUID (like String but for IDs), JSONB (like Map but queryable with ->> operator), TEXT[] or INTEGER[] (like Array but supports JOINs via ANY()). Key Supabase advantages over Firestore for type handling: SQL supports SUM, AVG, COUNT on numeric fields (Firestore cannot), NUMERIC type prevents floating-point rounding errors in financial calculations, TIMESTAMPTZ handles timezone-aware date math correctly, and FOREIGN KEY enforces DocumentReference-style relationships at the database level.

Expected result: You understand when Supabase's type system offers advantages for your specific data model over Firestore types.

Complete working example

firestore_type_reference.txt
1FlutterFlow Firestore Data Type Reference
2
3TYPE FLUTTER TYPE USE FOR QUERY SUPPORT
4----------- ------------ ------------------- ---------------
5String String names, emails, ==, !=,
6 status, URLs >, <, >=, <=,
7 array-contains
8
9Integer int counts, ages, ==, !=,
10 quantities >, <, >=, <=
11
12Double double prices, coords, ==, !=,
13 percentages >, <, >=, <=
14
15Boolean bool flags, toggles == true/false
16
17Timestamp DateTime dates, times ==, !=,
18 (always UTC) >, <, >=, <=
19
20GeoPoint LatLng coordinates, == only
21 locations (use GeoHash
22 for proximity)
23
24DocRef DocumentRef relationships == only
25 (pointer to doc) (fetch doc)
26
27Array List<T> tags, UIDs, array-contains
28 product lists arrayContainsAny
29
30Map Map<String,T> address, metadata, not queryable
31 settings (use top-level
32 for queries)
33
34Null null absent values isNull / notNull
35
36COMMON MISTAKES:
37 Price as String cannot range query
38 Date as String cannot sort/filter
39 Count as String cannot do math
40 Array unbounded hits 1MB document limit
41 Map for queries cannot filter by map key

Common mistakes

Why it's a problem: Storing prices as String ('19.99') instead of Double (19.99)

How to avoid: Use Double for all numeric values that you will query, sort, or calculate. If you need to display prices with currency symbols, use a Custom Function to format the Double as a string for display only: formatPrice(product.price) returns '$19.99'.

Why it's a problem: Using an Array inside a document for data that will grow indefinitely

How to avoid: Use subcollections for data that grows over time. Instead of user.orderHistory as an Array, create an orders/{userId}/items/{itemId} subcollection. Each item is an independent document that can be individually queried, paginated, and indexed.

Why it's a problem: Storing dates as formatted strings ('2024-03-15') instead of Timestamps

How to avoid: Always use Timestamp type for dates and times. FlutterFlow maps Timestamp to DateTime natively. Use DateTimePicker for user input, Current Date Time for now(), and Custom Functions for any formatting needed for display.

Best practices

  • Document your Firestore schema with the collection name, field names, and types in a text file shared with your team — field names are case-sensitive and a typo breaks every query using that field
  • Use String for enum-like values (status: 'active', 'pending', 'completed') and validate them in Firestore security rules with the in operator
  • Prefer Integer over Double for counts and quantities to avoid floating-point arithmetic surprises in calculations
  • Never store sensitive data like passwords, API keys, or payment card numbers in Firestore documents — use Firebase Auth for passwords and Cloud Functions for handling payment data
  • Use DocumentReference fields for one-to-many relationships (post has an authorId DocumentReference pointing to the users collection) rather than duplicating user data in every post
  • Add a createdAt Timestamp and updatedAt Timestamp to every document — these are essential for debugging, sorting, and audit trails
  • For Supabase users: use NUMERIC(10,2) instead of FLOAT8 for financial amounts to avoid floating-point rounding errors in currency calculations

Still stuck?

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

ChatGPT Prompt

I am designing a Firestore schema for a FlutterFlow e-commerce app. I have these entities: products (with name, description, price, category, tags, inventory count, isAvailable, createdAt), orders (with userId, items list, total amount, status, shippingAddress, createdAt), and users (with name, email, role, location, createdAt). For each field, recommend the correct Firestore data type (String, Integer, Double, Boolean, Timestamp, GeoPoint, Array, Map, DocumentReference) and explain why that type is the correct choice over alternatives.

FlutterFlow Prompt

In my FlutterFlow Firestore collection, I have a products collection where I accidentally stored the price field as a String type instead of Double. I cannot change the type of an existing field in Firestore without migrating the data. Write me a Firebase Cloud Function that reads all documents in the products collection, converts the price field from String to Double (parseFloat), and writes the corrected data back to each document using batch writes. Handle potential errors for documents where the price string cannot be parsed to a number.

Frequently asked questions

Can I change a Firestore field's data type after the collection is created?

In FlutterFlow's Firestore panel, you cannot change the type of an existing field — you must delete and recreate it. However, Firestore itself is schemaless, so the actual stored data type is set per document when you write it. To migrate existing data to a new type (e.g., price from String to Double), write a Firebase Cloud Function that reads each document, converts the field value, and writes it back. Test on a small batch first before running on all documents.

What is the difference between Integer and Double in FlutterFlow?

Integer stores whole numbers with no decimal component: 1, 42, 1000. It is perfect for counts, quantities, and sequential IDs. Double stores decimal numbers: 19.99, 3.14, 0.85. Use Double for prices, percentages, GPS coordinates, and measurements. Using Double for a count field works functionally but wastes bytes and can cause unexpected decimal values in arithmetic. Using Integer for a price field causes all prices to round to whole numbers.

How do I store a list of user IDs (UIDs) in a Firestore document?

Use an Array of String type. In FlutterFlow's Firestore panel, add a field with type Array and set the array element type to String. Store each UID as a string element in the array (e.g., likedBy: ['uid123', 'uid456', 'uid789']). Query documents where a specific user has liked: use the arrayContains filter operator in your Backend Query with the current user's UID as the value. Use FieldValue.arrayUnion and FieldValue.arrayRemove in Update Document actions to add and remove UIDs without replacing the entire array.

When should I use a Map field vs creating separate top-level fields?

Use a Map when the sub-fields are always read together and never individually queried. Address is a perfect Map candidate — you always show the full address together and never need to query WHERE address.city == 'London'. Use separate top-level fields when you need to query, sort, or filter by individual sub-values. A product's price and category should be separate top-level fields (not inside a details Map) because you filter by price and category constantly.

What data type should I use for storing files and images?

Never store binary file data in Firestore — the document size limit is 1MB and images are typically larger. Store files in Firebase Storage. In Firestore, store the download URL as a String field pointing to the Firebase Storage file. For multiple images, use an Array of Strings. For images with metadata, use an Array of Maps: [{url: 'https://...', caption: 'Front view', order: 1}].

Does FlutterFlow support Supabase data types for apps using PostgreSQL instead of Firestore?

Yes. When you connect Supabase via Settings → Integrations → Supabase, FlutterFlow reads your PostgreSQL schema and maps SQL types to Flutter types: TEXT → String, INTEGER → int, FLOAT8/NUMERIC → double, BOOLEAN → bool, TIMESTAMPTZ → DateTime, UUID → String, JSONB → dynamic/Map. You design your Supabase schema in the Supabase Dashboard SQL editor or Table Editor, then click Get Schema in FlutterFlow to import the types automatically.

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.