Connect FlutterFlow to MongoDB using the MongoDB Atlas Data API — HTTPS endpoints that accept JSON and return documents without any TCP socket or native driver. In FlutterFlow, create an API Group pointed at your Atlas Data API base URL with an `api-key` header, add calls for `find`, `insertOne`, and `updateOne`, parse `$.documents` into a Data Type, and bind to your ListView. Secret write-capable keys should proxy through a Cloud Function.
| Fact | Value |
|---|---|
| Tool | MongoDB |
| Category | Database & Backend |
| Method | FlutterFlow API Call |
| Difficulty | Intermediate |
| Time required | 40 minutes |
| Last updated | July 2026 |
MongoDB Atlas Data API: The Right Bridge for FlutterFlow
MongoDB is one of the most widely used databases for app backends — its flexible document model is a natural fit for the varied, schema-optional data that mobile apps produce. MongoDB Atlas, the managed cloud version, offers a free M0 cluster with 512MB of storage, which is enough to build and launch an MVP. Paid dedicated clusters start at roughly $0.08 per hour depending on region and tier (verify current pricing in the Atlas documentation).
The challenge with FlutterFlow is that MongoDB's standard connection mechanism — the `mongodb+srv://username:password@cluster.mongodb.net/database` connection string — requires a persistent TCP socket on port 27017. A Flutter app compiled by FlutterFlow runs on users' phones and browsers. Storing the database password in a Dart custom action ships it to every user who downloads the app, and the `mongo_dart` package that wraps this connection requires `dart:io` sockets, which are unavailable in web builds entirely. This is not a minor inconvenience — it is a fundamental architecture mismatch.
The MongoDB Atlas Data API is the purpose-built answer. It exposes your Atlas cluster through standard HTTPS endpoints, authenticated with an API key header instead of a connection string. You POST a JSON body that describes the operation — which collection, which filter, which documents to return — and the API sends back JSON. Every FlutterFlow-supported platform (iOS, Android, web) can make HTTPS requests, so the Data API works everywhere. Note: the Atlas Data API has had evolving availability notices from MongoDB; verify that it is available and enabled for your Atlas cluster tier before building your integration, as MongoDB's cloud offerings change. Check `cloud.mongodb.com` → your cluster → Data API for current status.
Integration method
MongoDB's native driver connects over TCP port 27017 with a connection string that includes your database username and password — a Flutter app running on users' devices cannot safely open that connection or hold those credentials. The MongoDB Atlas Data API solves this by exposing your cluster as a set of HTTPS endpoints (`/action/find`, `/action/insertOne`, etc.) authenticated by an API key header and returning plain JSON. FlutterFlow builds an API Group against those endpoints, maps `$.documents` to a Data Type, and binds the results to widgets — no Dart driver, no socket, no credentials on device.
Prerequisites
- A MongoDB Atlas account with at least a free M0 cluster created (cloud.mongodb.com)
- The Atlas Data API enabled on your cluster and an API key generated
- A FlutterFlow project where you want to display or write MongoDB data
- A Firebase project (Blaze plan) or Supabase project for the Cloud Function proxy if you need write operations
- Basic familiarity with JSON and the FlutterFlow API Calls panel
Step-by-step guide
Enable the Atlas Data API and Create an API Key
Log into cloud.mongodb.com and navigate to your project. In the left sidebar, find 'Data API' under the App Services section (it may also appear under your cluster's 'Connect' options depending on your Atlas UI version). Click 'Enable the Data API' — you will be asked to select which data sources (clusters) to enable it on; select your cluster. Once enabled, Atlas shows you a Data API base URL that looks like `https://data.mongodb-api.com/app/{app-id}/endpoint/data/v1`. Copy this URL — you will use it as the base URL in your FlutterFlow API Group. Next, create an API key by clicking 'Create API Key'. Give it a descriptive name like 'FlutterFlow-ReadOnly'. Atlas generates a key string starting with characters you should treat as sensitive — copy it immediately because it is only shown once. For reading data in FlutterFlow (fetching documents to display), you can use this key directly in the API Call header. For writing data (insertOne, updateOne, deleteOne), create a separate key with write access that you will store only in your Cloud Function — never in FlutterFlow itself. Note that the Atlas Data API availability and UI may vary by Atlas tier and region; if you do not see the Data API option, check MongoDB's current documentation at mongodb.com/docs/atlas/api/data-api/ for your specific tier.
Pro tip: Create two API keys: one read-only key for FlutterFlow (to display data) and one read-write key stored only in your Cloud Function (for creating and updating documents). This limits the blast radius if the client-side key is ever exposed.
Expected result: The Atlas Data API panel shows your cluster as enabled, you have a Data API base URL copied, and at least one API key has been created and saved securely.
Build the FlutterFlow API Group for MongoDB Atlas Data API
In FlutterFlow, click 'API Calls' in the left navigation panel, then click '+ Add' → 'Create API Group'. Name the group 'MongoDB'. Set the Base URL to your Atlas Data API URL: `https://data.mongodb-api.com/app/{your-app-id}/endpoint/data/v1` — replace `{your-app-id}` with the actual app ID from your Atlas console. In the 'Headers' section, add two shared headers that will apply to all calls in this group: `api-key` set to your read-only API key value, and `Content-Type` set to `application/json`. Now add your first API Call inside this group: click '+ Add API Call', name it 'FindDocuments', and set the method to POST and the endpoint to `/action/find`. Switch to the 'Variables' tab and add variables for `collection` (String), `filter` (String, optional — a JSON filter object), and `limit` (Integer, default 20). Switch to the 'Body' tab, set body type to JSON, and enter the body template. The `dataSource` field must match your cluster name (usually 'Cluster0'), `database` must match your database name, and `collection` uses the `{{ collection }}` variable. Add a `filter` field mapping to `{{ filter }}` and a `limit` field mapping to `{{ limit }}`.
1{2 "dataSource": "Cluster0",3 "database": "your-database-name",4 "collection": "{{ collection }}",5 "filter": {{ filter }},6 "limit": {{ limit }}7}Pro tip: The `filter` variable should be a JSON object like `{}` for all documents or `{"status": "active"}` for filtered results. Pass it as a String variable and let FlutterFlow interpolate it directly into the body.
Expected result: The MongoDB API Group appears in the API Calls panel with at least the 'FindDocuments' call listed inside it.
Test the API Call and Map the Response to a FlutterFlow Data Type
Switch to the 'Response & Test' tab on your FindDocuments call. You need to run a real test to generate the JSON Path mappings. Fill in the test variable values: set `collection` to the name of a collection you have already created in Atlas (e.g. 'products'), set `filter` to `{}` (to fetch all documents), and set `limit` to 5. Click 'Test API Call'. If everything is configured correctly, you will see a JSON response like `{ "documents": [{ "_id": { "$oid": "..." }, "name": "...", "price": 29.99 }, ...] }`. FlutterFlow will offer to auto-generate JSON Paths — click 'Generate JSON Paths'. Next, create a Data Type to hold the parsed document. Go to 'Data Types' in the left panel and create a new type called 'MongoProduct' (or whatever matches your collection). Add fields matching the document fields you care about: for a product, that might be `id` (String, mapped from `$._id.$oid`), `name` (String), `price` (Double). Back in the API Call, go to the JSON Paths section and map `$.documents` to a List of MongoProduct. Map the nested field `$._id.$oid` to the `id` field — the `$oid` wrapper is MongoDB's way of representing ObjectIDs and you must extract the inner string, not use the `{ "$oid": "..." }` object directly. With this mapped, you can bind the API Call response to a ListView and access individual fields on each item.
Pro tip: If your collection is empty, the test returns `{ "documents": [] }` and FlutterFlow cannot auto-generate paths. Add at least one test document in Atlas before running the test, or paste a sample response manually into the response editor.
Expected result: The test response shows your documents, JSON Paths are generated, and the MongoProduct Data Type has fields mapped from the response — you can now bind this API Call to a ListView on any page.
Add insertOne and updateOne Calls (via Cloud Function Proxy for Writes)
Reading data with the read-only API key in FlutterFlow is fine — the key grants limited access and displaying documents publicly is acceptable for many apps. Writing data is different. An `insertOne` or `updateOne` key that lives in FlutterFlow ships to every device, and any malicious user can use it to write arbitrary data to your MongoDB database. The safe pattern: route all write operations through a Firebase Cloud Function (or Supabase Edge Function) that holds a separate write-capable API key in its environment config. FlutterFlow POSTs the write payload to the Cloud Function, the Function adds the `api-key` header and forwards the request to the Atlas Data API. For reading-only apps or apps where the write risk is acceptable (internal tools with no public users), you can add the write calls directly in FlutterFlow using the same API Group but a different API key — but this is not recommended for consumer apps. For the `updateOne` call, pay close attention to the filter: to update a specific document by its ID, the filter must use `{ "_id": { "$oid": "your-id-string" } }` — passing the `_id` as a plain string will fail with a 400 error. Store the `$oid` string from the find response in a page variable, then construct the filter body with it before calling update. If you're building the proxy function, the Cloud Function simply receives the body from FlutterFlow, appends `{ 'api-key': process.env.MONGO_WRITE_KEY }` to the request headers, and forwards to `https://data.mongodb-api.com/app/{app-id}/endpoint/data/v1/action/insertOne` using `fetch` or the axios library. Deploy the Function and add a second API Call in FlutterFlow pointing to the Function URL instead of Atlas directly.
1// Firebase Cloud Function proxy for MongoDB writes (Node.js)2const { onRequest } = require('firebase-functions/v2/https');3const axios = require('axios');45exports.mongoWrite = onRequest({ cors: true }, async (req, res) => {6 if (req.method !== 'POST') return res.status(405).send('Method Not Allowed');78 const { action, ...body } = req.body;9 // action = 'insertOne' | 'updateOne' | 'deleteOne'10 const validActions = ['insertOne', 'updateOne', 'deleteOne'];11 if (!validActions.includes(action)) {12 return res.status(400).json({ error: 'Invalid action' });13 }1415 const url = `https://data.mongodb-api.com/app/${process.env.MONGO_APP_ID}/endpoint/data/v1/action/${action}`;16 try {17 const response = await axios.post(url, body, {18 headers: {19 'api-key': process.env.MONGO_WRITE_KEY,20 'Content-Type': 'application/json',21 },22 });23 return res.status(200).json(response.data);24 } catch (err) {25 const status = err.response?.status || 500;26 return res.status(status).json({ error: err.response?.data || err.message });27 }28});Pro tip: Always validate and sanitize the `action` parameter in the Cloud Function — only allow the specific actions your app needs (e.g. 'insertOne') to prevent write abuse through the proxy.
Expected result: The Cloud Function deploys and you can test it with a POST request, seeing the document appear in your Atlas collection. FlutterFlow's write API Call points to the Function URL and passes through cleanly.
Bind Data to FlutterFlow Widgets and Handle _id.$oid in Updates
With the API calls working, connect them to your FlutterFlow UI. For reading: select a ListView widget on your page, open its properties, and set the 'Backend Query' to your MongoDB FindDocuments API Call. Pass the collection name as a constant variable and the filter as a dynamic variable if users can filter data. Each ListTile inside the ListView can now bind its fields to the API response — click the 'field binding' icon next to a Text widget, navigate through API Response → FindDocuments → documents → [index] → name (or whichever field you mapped). For a Card with an image, bind the image URL field the same way. For update flows, you need to pass the document's `_id` through your UI. When a user taps a list item to edit it, navigate to the edit page and pass the document's `id` field (the `$oid` string you extracted) as a page parameter. On the edit page, when the user submits, construct the update filter in a 'Set Variable' action before calling the write API: build the JSON string `{"_id": {"$oid": "<passed-id>"}}` using string interpolation with the page parameter. Pass this as the `filter` body field in your write call (either direct or proxied). If you pass the `_id` as a plain string without the `$oid` wrapper, Atlas will return a 400 error saying no matching document was found — this is one of the most common MongoDB+FlutterFlow mistakes and it is easy to miss. If you'd rather skip debugging this, RapidDev's team sets up MongoDB integrations in FlutterFlow regularly — free scoping call at rapidevelopers.com/contact.
Pro tip: Store the _id string ($oid value) in a page state variable when the user taps a list item. Use it to build the filter for updateOne/deleteOne calls — never use the raw { "$oid": "..." } object as a string; extract only the inner string and wrap it again when constructing the filter.
Expected result: Your ListView displays MongoDB documents with live data from your Atlas cluster, and editing a document updates the correct record matched by its ObjectID.
Common use cases
Content app that displays articles stored as MongoDB documents
A FlutterFlow blog or news app uses a MongoDB Atlas collection to store articles as documents with fields like title, body, category, and publishedAt. The app's home screen fires a `find` call filtered by category and sorted by date, mapping `$.documents` to a ListView that renders each article card.
Build a home screen that calls the MongoDB Atlas Data API to fetch all published articles from the 'articles' collection, filters by the selected category, and displays them in a ListView sorted by publish date descending.
Copy this prompt to try it in FlutterFlow
User feedback app that writes submissions to MongoDB
A FlutterFlow app collects in-app feedback using a form. On submit, an Action Flow calls an `insertOne` endpoint to write the feedback document (userId, rating, comment, timestamp) into a MongoDB collection. A Cloud Function proxy handles the write so the write-capable API key stays server-side.
Create a feedback form that, on submission, POSTs the form data to a Cloud Function which inserts a new feedback document into MongoDB Atlas, then navigates to a thank-you screen.
Copy this prompt to try it in FlutterFlow
Inventory management app that reads and updates product stock
A FlutterFlow admin panel for a small business fetches product inventory from a MongoDB collection using a `find` call, displays items in a DataTable, and lets the admin update stock quantities via an `updateOne` call that matches on `_id.$oid`. Write operations are gated behind a Cloud Function to keep the write key off the client.
Build an inventory screen that lists all products from MongoDB with their current stock levels, and includes an edit dialog that updates the stock field for a specific document matched by its _id using an updateOne call through a Cloud Function.
Copy this prompt to try it in FlutterFlow
Troubleshooting
API Call returns 400 with 'no document found' or 'no match' when trying to update a document
Cause: The `_id` field is being passed as a plain string in the filter instead of the required `{ "$oid": "..." }` object shape. MongoDB ObjectIDs have a special BSON type that the Data API expects to be wrapped this way.
Solution: Extract the string value from the `$oid` field when you read documents (map it to a String field in your Data Type). When constructing the filter for updateOne or deleteOne, build the JSON body as: `{"_id": {"$oid": "YOUR_ID_STRING"}}` — use a Set Variable action to build this string with the stored ID interpolated inside the $oid quotes.
FlutterFlow API test returns 401 Unauthorized or 403 Forbidden
Cause: The `api-key` header value is incorrect, has expired, or the API key does not have permission for the requested action (e.g. a read-only key is being used on a write endpoint).
Solution: Go to Atlas → App Services → Data API → API Keys and verify the key is active and not expired. Check that the exact key string is in your FlutterFlow API Group header — no extra spaces or line breaks. For write endpoints, confirm you are using a key with read-write permissions, not the read-only key you created for display calls.
API Call works in FlutterFlow Test mode but fails on the web build with a CORS error (XMLHttpRequest error)
Cause: The Atlas Data API returns CORS headers, but if you are routing through a Cloud Function and that Function is missing CORS headers, web builds will be blocked by the browser's CORS enforcement.
Solution: If you are hitting the Atlas Data API directly from FlutterFlow (not through a proxy), this typically works because Atlas includes permissive CORS headers. If you are routing through a Cloud Function, ensure the Function sets `Access-Control-Allow-Origin: *` (or your specific domain) and handles OPTIONS preflight requests. For Firebase Functions v2, add `cors: true` to `onRequest` options.
Custom Action using mongo_dart package fails on web with 'Unsupported operation: Socket' error
Cause: The `mongo_dart` package connects to MongoDB over TCP on port 27017 using `dart:io` sockets, which are not available in Flutter web builds.
Solution: Do not use `mongo_dart` in a FlutterFlow Custom Action for web-targeted apps. Switch to the Atlas Data API approach described in this guide — it uses standard HTTPS and works on all platforms. If you specifically need mobile-only connectivity and have code export available, `mongo_dart` can work on iOS/Android only, but even then it requires the database password in the connection string which is a security risk.
Best practices
- Use the Atlas Data API (HTTPS) instead of the mongo_dart package — the Data API works on iOS, Android, and web builds, while mongo_dart only works on mobile and leaks database credentials.
- Create separate API keys for reads and writes — put the read key in FlutterFlow for display-only calls, and keep the write key exclusively in a Cloud Function environment variable.
- Always extract `_id.$oid` as a plain String field in your Data Type and reconstruct the `{ "$oid": "..." }` wrapper only when needed for update/delete filters.
- Restrict your Atlas cluster IP access list to allow only your Cloud Function's service account or IP range rather than using 0.0.0.0/0 in production — this limits exposure if credentials are compromised.
- Add a `limit` field to every `find` call and a `sort` field for consistent ordering — MongoDB does not guarantee document order without an explicit sort, and unlimited queries will slow down as your collection grows.
- Check that the Atlas Data API is still available for your cluster tier before building your integration — MongoDB has periodically modified Data API availability, so verify at mongodb.com/docs/atlas/api/data-api/ before committing to this architecture.
- Use Supabase or Firebase as the primary backend for FlutterFlow apps that need real-time updates — MongoDB's Data API is request-response only and does not support WebSocket subscriptions for live data.
- Map only the fields your UI actually needs in your Data Type — avoid mapping entire documents if your collections have many fields, as this keeps your Data Types clean and your bindings easy to manage.
Alternatives
Firebase has a native FlutterFlow integration with visual query builders, real-time listeners, and built-in auth — it is the lowest-friction database option for FlutterFlow apps that do not already use MongoDB.
Airtable offers a simpler REST API with a Bearer token and spreadsheet-style UI for managing content — a better choice for non-technical teams who need to edit data without touching a database interface.
PostgreSQL via Supabase gives you a native FlutterFlow integration with SQL querying, row-level security, and real-time subscriptions — ideal if you prefer relational data modeling over MongoDB's document approach.
Frequently asked questions
Can I connect FlutterFlow directly to a self-hosted MongoDB instance (not Atlas)?
Not safely. A self-hosted MongoDB instance accepts connections on TCP port 27017 with a `mongodb+srv://` connection string that includes your database credentials. Putting that connection string in FlutterFlow means it compiles into your app and is visible to anyone who decompiles it. You would need to stand up your own REST proxy in front of the self-hosted instance (similar to a Cloud Function) that exposes safe HTTPS endpoints, which is effectively the same architecture as the Atlas Data API but with more setup work.
Is the MongoDB Atlas Data API available on the free M0 cluster?
Availability of the Data API on free M0 clusters has changed over time as MongoDB has evolved its product offerings. As of this writing, the Data API has been available on M0, but MongoDB periodically modifies access. Check the Atlas console under your cluster's Data API section or the official docs at mongodb.com/docs/atlas/api/data-api/ for the current status on your cluster tier before building your integration.
How do I display real-time data from MongoDB in FlutterFlow — like a live feed?
The MongoDB Atlas Data API is request-response only — it does not support WebSocket connections or push-based real-time updates. For real-time data in FlutterFlow, the recommended pattern is to use MongoDB as your primary database but write a backend service (Cloud Function or dedicated server) that listens to MongoDB change streams and writes updates into Firestore or Supabase Realtime, which FlutterFlow does support natively with live listeners. Alternatively, switch to Firebase Firestore or Supabase if real-time data is core to your app.
What is the sibling mongodb-atlas page and how is it different?
The `mongodb-atlas` integration page covers MongoDB Atlas as a managed platform, including cluster setup, Atlas Search, vector search, and Atlas-specific features like triggers and scheduled functions. This page focuses specifically on the Data API as the mechanism for connecting FlutterFlow to any MongoDB Atlas cluster. If you want to dig deeper into Atlas platform features beyond basic read-write operations, check the mongodb-atlas integration guide.
Do I need to pay for a FlutterFlow Pro plan to use MongoDB?
No. The API Calls panel is available on all FlutterFlow plans, including the free tier. You can build, test, and publish an app that reads and writes MongoDB data through the Data API without upgrading. The Pro plan ($70/month) is only needed if you want to export your Flutter code locally to manage dependencies like pub.dev packages or write Cloud Functions outside of the Firebase console.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation