Real Estate Listing Backend Template
Flutter — Schema, Geo-Queries & AI Guide
A production-ready Flutter real estate listing backend on Back4app: listings, leads, favorites, geo-queries, ER diagram, data dictionary, JSON schema, API playground, and a one-click AI Agent prompt to deploy in minutes.
Key Takeaways
On this page you get a production-ready real estate schema, a one-click AI prompt, and step-by-step Flutter code — so you can ship a property listing app without building the backend.
- Deploy in minutes — Paste the AI Agent prompt and get a running app with property list, geo search, lead capture, and favorites.
- Geo-queries out of the box — Property.location (GeoPoint) supports $nearSphere for "properties near me" and map-based search.
- Flutter-native SDK — Typed objects, async/await, optional offline pinning, and Live Queries for new listings.
- REST + GraphQL — Both APIs auto-generated; filter by status, beds, price; sort by distance or date.
- Four classes — _User (built-in), Property, Lead (inquiries), Favorite (saved listings).
What Is the Flutter Real Estate Listing Backend Template?
Back4app is a backend-as-a-service (BaaS) ideal for real estate listing apps: managed backend, auth, geo-queries, and SDKs for 13+ technologies. The Flutter Real Estate Listing Backend Template is a pre-built schema on Back4app with auth (User), listings (Property), inquiries (Lead), and saved properties (Favorite). You get geo-queries, lead capture, and a one-click AI Agent prompt — connect a Flutter frontend and ship a working property listing app in minutes.
Best for:
Overview
A real estate listing app needs property CRUD, geo-queries for map search, lead capture (inquiries per property), and user favorites. Under the hood it needs auth, Property with location (GeoPoint), Lead linked to Property, and Favorite linking User to Property.
The schema (see ER diagram below) covers users, properties, leads, and favorites. With the Back4app Flutter SDK, you can query properties (including geo), create leads, and manage favorites — without writing a custom API layer.
Core Real Estate Listing Features
This backend template includes the following features out of the box.
Property listings
Property with title, price, address, location (GeoPoint), beds, baths, status. List and filter by status, price, or geo.
Lead capture
Lead links name, email, phone, message to a Property. Capture inquiries from listing detail pages.
Saved properties
Favorite links user and property. List favorites for the current user; add or remove from listing detail.
Geo-queries
Property.location (GeoPoint) supports $nearSphere. Find properties near a point; sort by distance.
User & permissions
Built-in _User; restrict Property create/update to agents; public read for list and detail.
Why Build Your Real Estate Listing Backend with Back4app?
Back4app gives you a ready backend with geo-queries and lead capture so you can build your property listing app without writing REST glue or managing auth yourself.
- •Geo-queries & SDK: Property.location (GeoPoint) supports $nearSphere; the SDK keeps Property and Lead type-safe.
- •Lead capture & favorites: Lead class stores inquiries per property; Favorite links user and property for saved listings.
- •Live Queries: Subscribe to Property or Favorite changes so the UI updates in real time.
Same schema and APIs for every stack — switch clients later without changing the backend.
Core Benefits
A production-ready real estate backend so you can ship faster and focus on your app.
Ship Faster, No Backend Code
REST & GraphQL APIs and a ready schema — connect your app and go.
Geo-Queries Out of the Box
Find properties near a point with $nearSphere; sort by distance.
Lead Capture
Lead class stores name, email, phone, message, and property pointer.
Built-In Auth
User sign-up, login, and session handling; restrict favorites and listing management.
Works Offline
Local pinning keeps properties and favorites available offline and syncs when you reconnect.
Deploy in Minutes
Use the AI Agent to create and deploy your real estate app from this template.
Ready to try it?
Let the Back4app AI Agent create your real estate listing backend, connect the Flutter frontend, and deploy — all from a single prompt.
Free to start — 50 AI Agent prompts/month, no credit card required
Technical Stack
Everything powering this real estate listing template at a glance.
ER Diagram
Entity-Relationship diagram for the Flutter real estate listing data model.
Schema: _User, Property, Lead, Favorite with pointers for listedBy, property, user.
View diagram source
erDiagram
_User {
String objectId PK
String username
String email
String password
Date createdAt
Date updatedAt
}
Property {
String objectId PK
String title
String description
Number price
String address
GeoPoint location
Number beds
Number baths
Number area
String propertyType
String status
Pointer listedBy FK
Date createdAt
Date updatedAt
}
Lead {
String objectId PK
String name
String email
String phone
String message
Pointer property FK
Date createdAt
Date updatedAt
}
Favorite {
String objectId PK
Pointer user FK
Pointer property FK
Date createdAt
Date updatedAt
}
_User ||--o{ Property : "listedBy"
_User ||--o{ Favorite : "user"
Property ||--o{ Lead : "property"
Property ||--o{ Favorite : "property"
Integration Flow
Auth-to-CRUD sequence: how your Flutter app talks to Back4app — login, query properties (with geo), create lead, manage favorites.
View diagram source
sequenceDiagram
participant User
participant App as Flutter App
participant Back4app as Back4app Cloud
User->>App: Login
App->>Back4app: Authenticate (username, password)
Back4app-->>App: Session token
App-->>User: Logged in
User->>App: Load data
App->>Back4app: Query Property and Lead
Back4app-->>App: List of Property / Lead
App-->>User: Show list
User->>App: Create or update
App->>Back4app: Save Property
Back4app-->>App: Property (objectId)
App-->>User: Updated listData Dictionary
Complete field reference for every class in the schema.
| Field | Type | Description | Required |
|---|---|---|---|
| objectId | String | Auto-generated unique identifier | auto |
| title | String | Listing title | |
| description | String | Full listing description | — |
| price | Number | Asking or rental price | — |
| address | String | Street address | — |
| location | GeoPoint | Lat/lng for geo-queries and map display | — |
| beds | Number | Number of bedrooms | — |
| baths | Number | Number of bathrooms | — |
| area | Number | Area in sq ft or sq m | — |
| propertyType | String | e.g. house, apartment, land | — |
| status | String | e.g. for_sale, for_rent, sold | — |
| listedBy | Pointer<_User> | User who created the listing | — |
| createdAt | Date | Auto-generated creation timestamp | auto |
| updatedAt | Date | Auto-generated last-update timestamp | auto |
14 fields in Property
Security & Permissions
How ACLs and class-level permissions protect data in this real estate schema.
Property & public read
Allow public read for Property list and detail; restrict create/update/delete to authenticated users (e.g. listing agents).
Class-Level Permissions
CLPs restrict create/read/update/delete per class. Lead creation can be public; Favorite and Property writes typically require auth.
Pointer-based relations
listedBy links Property to _User; Favorite links user and property. Use Cloud Code to enforce ownership where needed.
Schema (JSON)
Raw JSON schema definition — copy and use in your Back4app app or import via the API.
{
"classes": [
{
"className": "Property",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"title": {
"type": "String",
"required": true
},
"description": {
"type": "String",
"required": false
},
"price": {
"type": "Number",
"required": false
},
"address": {
"type": "String",
"required": false
},
"location": {
"type": "GeoPoint",
"required": false
},
"beds": {
"type": "Number",
"required": false
},
"baths": {
"type": "Number",
"required": false
},
"area": {
"type": "Number",
"required": false
},
"propertyType": {
"type": "String",
"required": false
},
"status": {
"type": "String",
"required": false
},
"listedBy": {
"type": "Pointer",
"targetClass": "_User",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "Lead",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"name": {
"type": "String",
"required": true
},
"email": {
"type": "String",
"required": true
},
"phone": {
"type": "String",
"required": false
},
"message": {
"type": "String",
"required": false
},
"property": {
"type": "Pointer",
"targetClass": "Property",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "Favorite",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"user": {
"type": "Pointer",
"targetClass": "_User",
"required": false
},
"property": {
"type": "Pointer",
"targetClass": "Property",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "_User",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"username": {
"type": "String",
"required": true
},
"email": {
"type": "String",
"required": true
},
"password": {
"type": "String",
"required": true
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
}
]
}Build with AI Agent
Use the Back4app AI Agent to build a real real estate listing app from this template: it will create the frontend, the backend (this schema, auth, geo-queries, and APIs), and deploy it — no manual setup.
Create a real estate listing app on Back4app with this exact schema and behavior. Schema: 1. _User (use Back4app built-in): username (String, required), email (String, required), password (String, required); objectId, createdAt, updatedAt (system). 2. Property: title (String, required), description (String), price (Number), address (String), location (GeoPoint), beds (Number), baths (Number), area (Number), propertyType (String), status (String; e.g. for_sale, for_rent, sold), listedBy (Pointer to _User); objectId, createdAt, updatedAt (system). 3. Lead: name (String, required), email (String, required), phone (String), message (String), property (Pointer to Property); objectId, createdAt, updatedAt (system). 4. Favorite: user (Pointer to _User), property (Pointer to Property); objectId, createdAt, updatedAt (system). Security: - Set ACLs so only authenticated users can create/update/delete Property and Favorite; allow public read for Property list and detail. Lead creation can be public or require auth. - Use Class-Level Permissions so only authenticated users can manage Favorite; Property and Lead as needed for your use case. Auth: - Sign-up (username, email, password) and login; support logout/session. Behavior: - Full CRUD for Property (for listing agents) and Favorite. - Create Lead (inquiry) linked to a Property; list leads by property or by current user's listings. - Geo query: find properties near a point using location (GeoPoint) with $nearSphere and limit. - Filter properties by status, beds, baths, price range, propertyType. - Optional: real-time Live Queries for new listings or favorite changes. Deliver: - Create the Back4app app with the schema above, ACLs, and any Cloud Code needed. - Generate the frontend and connect it to this backend; deploy so the app is runnable end-to-end. Use Flutter for the frontend with the Back4app Flutter SDK. Include screens for property list (with geo/map), property detail, lead form, and favorites; support offline pinning for saved listings.
Press the button below to open the Agent with this template's prompt pre-filled.
API Playground
Try the REST and GraphQL endpoints for the real estate schema. Responses from the example data above — no Back4app account needed.
Uses the same schema as this template.
Step-by-Step Flutter Integration
Connect to your Back4app backend from a Flutter app using the Back4app Flutter SDK.
Step 1: Install Back4app Flutter SDK
Add the Back4app SDK for your stack (e.g. npm, pubspec, or package manager).
YAMLdependencies: flutter: sdk: flutter parse_server_sdk_flutter: ^7.0.0Step 2: Initialize Back4app in your app
Initialize the Back4app SDK at app startup with your App ID and server URL.
Dartimport 'package:parse_server_sdk_flutter/parse_server_sdk_flutter.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Parse().initialize( 'YOUR_APP_ID', 'https://parseapi.back4app.com', clientKey: 'YOUR_CLIENT_KEY', autoSendSessionId: true, ); runApp(const MyApp()); }Step 3: Query properties (with optional geo)
Use the SDK to fetch Property objects; use geo query for "near me" or map results.
DartFuture<List<ParseObject>> getProperties({String status = 'for_sale'}) async { final query = QueryBuilder<ParseObject>(ParseObject('Property')) ..whereEqualTo('status', status) ..orderByDescending('createdAt'); final response = await query.query(); if (response.success && response.results != null) { return response.results as List<ParseObject>; } return []; } // Geo query: properties near a point Future<List<ParseObject>> getPropertiesNear(double lat, double lng, {int limit = 20}) async { final query = QueryBuilder<ParseObject>(ParseObject('Property')) ..setLocationConstraint('location', ParseGeoPoint(latitude: lat, longitude: lng), 50) ..setLimit(limit); final response = await query.query(); return response.success && response.results != null ? response.results as List<ParseObject> : []; }Step 4: Create a lead (inquiry)
Create a Lead with name, email, phone, message, and property pointer.
DartFuture<void> createLead(String name, String email, String propertyId, {String? phone, String? message}) async { final lead = ParseObject('Lead') ..set('name', name) ..set('email', email) ..set('property', ParseObject('Property')..objectId = propertyId); if (phone != null) lead.set('phone', phone); if (message != null) lead.set('message', message); final response = await lead.save(); if (response.success) { print('Lead created: ${response.result.objectId}'); } }Step 5: Manage favorites
Add or remove Favorite (user + property); list favorites for the current user.
Dart// Add favorite (user + property) Future<void> addFavorite(ParseUser user, String propertyId) async { final favorite = ParseObject('Favorite') ..set('user', user) ..set('property', ParseObject('Property')..objectId = propertyId); await favorite.save(); } // Remove favorite Future<void> removeFavorite(String favoriteId) async { final favorite = ParseObject('Favorite')..objectId = favoriteId; await favorite.delete(); } // List favorites for current user Future<List<ParseObject>> getMyFavorites(ParseUser user) async { final query = QueryBuilder<ParseObject>(ParseObject('Favorite')) ..whereEqualTo('user', user); final response = await query.query(); return response.success && response.results != null ? response.results as List<ParseObject> : []; }
State Management Integration
Integrate the Back4app SDK with your app's state layer (e.g. context, store, or services).
Full Data Model
Copy a complete Property/Lead/Favorite model for type-safe serialization (e.g. class, interface, or type definition).
class Property {
final String? objectId;
final String title;
final String? description;
final double? price;
final String? address;
final ParseGeoPoint? location;
final int? beds;
final int? baths;
final double? area;
final String? propertyType;
final String? status;
final String? listedById;
final DateTime? createdAt;
final DateTime? updatedAt;
Property({
this.objectId,
required this.title,
this.description,
this.price,
this.address,
this.location,
this.beds,
this.baths,
this.area,
this.propertyType,
this.status = 'for_sale',
this.listedById,
this.createdAt,
this.updatedAt,
});
factory Property.fromJson(Map<String, dynamic> json) {
return Property(
objectId: json['objectId'] as String?,
title: json['title'] as String,
description: json['description'] as String?,
price: (json['price'] as num?)?.toDouble(),
address: json['address'] as String?,
location: json['location'] != null ? ParseGeoPoint.fromJson(json['location']) : null,
beds: json['beds'] as int?,
baths: json['baths'] as int?,
area: (json['area'] as num?)?.toDouble(),
propertyType: json['propertyType'] as String?,
status: json['status'] as String? ?? 'for_sale',
listedById: json['listedBy'] is Map ? (json['listedBy'] as Map)['objectId'] as String? : null,
createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt']) : null,
updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt']) : null,
);
}
}
class Lead {
final String? objectId;
final String name;
final String email;
final String? phone;
final String? message;
final String? propertyId;
final DateTime? createdAt;
final DateTime? updatedAt;
Lead({
this.objectId,
required this.name,
required this.email,
this.phone,
this.message,
this.propertyId,
this.createdAt,
this.updatedAt,
});
factory Lead.fromJson(Map<String, dynamic> json) {
return Lead(
objectId: json['objectId'] as String?,
name: json['name'] as String,
email: json['email'] as String,
phone: json['phone'] as String?,
message: json['message'] as String?,
propertyId: json['property'] is Map ? (json['property'] as Map)['objectId'] as String? : null,
createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt']) : null,
updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt']) : null,
);
}
}
class Favorite {
final String? objectId;
final String? userId;
final String? propertyId;
final DateTime? createdAt;
final DateTime? updatedAt;
Favorite({
this.objectId,
this.userId,
this.propertyId,
this.createdAt,
this.updatedAt,
});
factory Favorite.fromJson(Map<String, dynamic> json) {
return Favorite(
objectId: json['objectId'] as String?,
userId: json['user'] is Map ? (json['user'] as Map)['objectId'] as String? : null,
propertyId: json['property'] is Map ? (json['property'] as Map)['objectId'] as String? : null,
createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt']) : null,
updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt']) : null,
);
}
}Offline-First & Local Datastore
Use pin() and unpin() so properties and favorites are available offline and sync when back online.
Supported SDKs include a local datastore. Pin Property and Favorite objects to keep them on device; query pinned data when offline. When the app is back online, sync with the server.
Below: pin results after fetch, and unpin when you no longer need local copies.
// Pin properties after fetch (offline-first)
Future<void> fetchAndPinProperties() async {
final query = QueryBuilder<ParseObject>(ParseObject('Property'))
..whereEqualTo('status', 'for_sale')
..orderByDescending('createdAt');
final response = await query.query();
if (response.success && response.results != null) {
final results = response.results!.cast<ParseObject>();
await ParseObject.pinAllObjects(results);
// Query from local store when offline:
// QueryBuilder<ParseObject>(ParseObject('Property')).fromLocalDatastore();
}
}
// Unpin when no longer needed
Future<void> unpinAllProperties() async {
await ParseObject.unpinAll('Property');
}Frequently Asked Questions
Common questions about the real estate listing backend template.
Ready to Build Your Real Estate Listing App?
Start your Flutter project in minutes. No credit card required.