# How to Integrate Satellite Imagery for Environmental Monitoring in FlutterFlow

- Tool: FlutterFlow
- Difficulty: Beginner
- Time required: 1.5-3 hours
- Compatibility: FlutterFlow Free+ (Google Maps API key required, Earth Engine API optional)
- Last updated: March 2026

## TL;DR

Integrate satellite imagery in FlutterFlow via Cloud Functions that call Google Earth Engine, Sentinel Hub, or NASA FIRMS APIs. Display data on a FlutterFlowGoogleMap using satellite tile overlays or colored polygon layers. Request mobile-appropriate tile resolution (256x256) not raw satellite files, which can be 100MB+. Add a date range Slider to browse historical imagery for time-series environmental analysis.

## Satellite imagery from space, displayed in your FlutterFlow app

Satellite data powers agriculture, forestry, urban planning, disaster response, and climate monitoring. APIs from Google Earth Engine, Copernicus Sentinel Hub, and NASA make this data publicly accessible. Integrating it into a FlutterFlow app means: routing API calls through Cloud Functions (satellite APIs require server-side authentication), fetching map tile URLs rather than raw image files (tile-based delivery is mobile-friendly), and displaying overlays on Google Maps using a Custom Widget. This tutorial covers four data sources — Earth Engine vegetation index, Sentinel Hub land cover, NASA FIRMS fire data, and Mapbox satellite basemap — with a focus on the practical FlutterFlow implementation for each.

## Before you start

- FlutterFlow project with Google Maps enabled (API key in Settings → Google Maps)
- Firebase project with Cloud Functions enabled (Blaze plan required)
- A Google Cloud project with Earth Engine API enabled (free for non-commercial use at signup.earthengine.google.com)
- Basic understanding of FlutterFlow Custom Widgets and Cloud Functions

## Step-by-step guide

### 1. Set up the NASA FIRMS fire data integration (simplest starting point)

NASA FIRMS (Fire Information for Resource Management System) provides active fire hotspot data as GeoJSON with no authentication required for basic queries. Create a Cloud Function named getFireData that takes a latitude, longitude, and radius in km. The function calls https://firms.modaps.eosdis.nasa.gov/api/area/csv?api_key={YOUR_KEY}&source=VIIRS_SNPP_NRT&area_of_interest={bbox}&date_range=1 where the bounding box is calculated from the center point and radius. Get a free API key at firms.modaps.eosdis.nasa.gov/api/area. The response is CSV — parse it to extract latitude, longitude, brightness (fire intensity), confidence, and acquisition time per hotspot. Return as JSON array. Register your FIRMS API key in FlutterFlow Secrets (Settings → Secrets) as FIRMS_API_KEY and read it in the Cloud Function via process.env.FIRMS_API_KEY.

**Expected result:** The Cloud Function returns active fire hotspot coordinates and intensity data for the requested area.

### 2. Display fire hotspots on FlutterFlowGoogleMap with custom markers

In your FlutterFlow app, add a FlutterFlowGoogleMap widget to a full-screen Container. Add an API Call in the API Manager pointing to your getFireData Cloud Function. In the Page's On Page Load action, call getFireData with the user's current location (or a default map center) and store the results in a Page State List variable named fireHotspots. On the FlutterFlowGoogleMap, add Markers bound to the fireHotspots list using Generate Dynamic Markers. Each marker uses latitude and longitude from the hotspot data. For marker color, use a Custom Function that converts confidence percentage to a color: confidence > 80 = red (high confidence fire), 50-80 = orange (medium), under 50 = yellow (low confidence). Tapping a marker shows a bottom sheet InfoWindow with the brightness temperature, satellite source, and acquisition time.

**Expected result:** Fire hotspots appear as colored map markers showing fire intensity and confidence level.

### 3. Integrate NDVI vegetation index from Google Earth Engine

Google Earth Engine (GEE) processes satellite imagery at scale. For vegetation health monitoring, NDVI (Normalized Difference Vegetation Index) measures plant health: values near 1.0 are dense green vegetation, near 0 is bare soil, negative values are water. Create a Cloud Function named getNDVITiles that authenticates with Earth Engine using a service account (download JSON key from Google Cloud Console → Service Accounts, store in Cloud Functions config), initializes ee.Initialize(credentials), then creates an NDVI image: ee.ImageCollection('LANDSAT/LC09/C02/T1_TOA').filterDate(startDate, endDate).median().normalizedDifference(['B5','B4']). Apply a color palette and generate a map tile URL using image.getMapId({min: -0.1, max: 0.9, palette: ['brown', 'yellow', 'lightgreen', 'darkgreen']}). Return the tile URL template. This URL is then used as a TileOverlay on your Google Map.

```
// Cloud Function: getNDVITiles
const ee = require('@google/earthengine');
const serviceAccount = require('./service-account.json');

exports.getNDVITiles = async (req, res) => {
  const { startDate, endDate } = req.query;

  // Authenticate with service account
  await new Promise((resolve, reject) => {
    ee.data.authenticateViaPrivateKey(
      serviceAccount,
      () => { ee.initialize(null, null, resolve, reject); },
      reject
    );
  });

  // Calculate NDVI from Landsat 9
  const ndvi = ee.ImageCollection('LANDSAT/LC09/C02/T1_TOA')
    .filterDate(startDate || '2024-01-01',
                endDate || '2024-12-31')
    .filterBounds(ee.Geometry.Rectangle(
      [-180, -60, 180, 70]))
    .median()
    .normalizedDifference(['B5', 'B4'])
    .rename('NDVI');

  // Get tile URL with color palette
  const mapId = await ndvi.getMapId({
    min: -0.1, max: 0.9,
    palette: ['8B4513', 'FFFF00',
              '90EE90', '006400']
  });

  res.json({ tileUrl: mapId.urlFormat });
};
```

**Expected result:** The Cloud Function returns a tile URL template that renders NDVI colors on the map.

### 4. Display satellite tile overlays with a Custom Widget

FlutterFlowGoogleMap supports marker overlays but not tile layers directly. Create a Custom Widget named SatelliteMapOverlay that wraps google_maps_flutter with TileOverlay support. Add google_maps_flutter: ^2.5.0 to Pubspec Dependencies. The widget takes a tileUrlTemplate (String) parameter. In the widget's GoogleMap constructor, add tileOverlays: {TileOverlay(tileOverlayId: TileOverlayId('satellite'), tileProvider: UrlTileProvider(tileUrlTemplate))}. In FlutterFlow, use this Custom Widget instead of the standard FlutterFlowGoogleMap for pages that need satellite imagery overlays. Position the widget to fill the screen, and layer FlutterFlow's standard UI controls (legend, date picker, info panel) on top using a Stack widget.

**Expected result:** The satellite NDVI or land cover tile layer renders on top of the base Google Maps tiles.

### 5. Add a date range slider for historical time-series imagery

Add a Slider widget to your environmental monitoring page. Set minimum to 0 and maximum to 11 (representing months 0-11 in the current year, or use a wider range for multi-year analysis). Store the slider value in a Page State variable named selectedMonth. Create a Custom Function named getDateRangeForMonth that converts the month integer to a start and end date string: month 0 returns startDate: '2024-01-01', endDate: '2024-01-31'. On Slider change, call getNDVITiles via your API Call with the new date range and update the tile URL. This lets users scrub through monthly NDVI changes to see deforestation events, drought progression, or seasonal crop cycles. Add month labels below the slider using a Custom Function that returns ['Jan', 'Feb', 'Mar', ...][selectedMonth].

**Expected result:** Users can slide through months to see how vegetation health or land cover changed over time.

## Complete code example

File: `satellite_monitoring_setup.txt`

```text
Satellite Imagery Integration Architecture

DATA SOURCES:
  1. NASA FIRMS (fire data)
     URL: firms.modaps.eosdis.nasa.gov/api/area
     Auth: free API key
     Output: fire hotspot GeoJSON
     Display: colored markers on FlutterFlowGoogleMap

  2. Google Earth Engine (NDVI, analysis)
     Auth: service account JSON key
     Package: @google/earthengine (Node.js)
     Output: map tile URL template
     Display: Custom Widget TileOverlay

  3. Sentinel Hub (land cover, true color)
     URL: services.sentinel-hub.com
     Auth: OAuth client credentials
     Output: PNG tiles or GeoTIFF
     Display: Custom Widget TileOverlay

  4. MapBox Satellite (basemap)
     URL: api.mapbox.com/styles/v1/mapbox/satellite-v9
     Auth: Mapbox access token
     Display: map style or tile overlay

FLUTTERFLOW PAGE STRUCTURE:
  Stack:
    SatelliteMapOverlay (full screen, Custom Widget)
    Container (controls overlay, top):
      Row: layer selector chips
    Container (timeline, bottom):
      Slider (month selector)
      Text (month labels)
    Container (legend, bottom-right):
      Column of color-labeled ranges
    BottomSheet (fire detail / pixel info)

KEY MOBILE CONSIDERATION:
  Request: 256x256 tile PNG (not raw image)
  Raw Sentinel-2 tile = 100MB+
  256px tile PNG = 10-50KB
  Always use tile server endpoints
```

## Common mistakes

- **Requesting raw satellite imagery instead of tile-optimized PNG files** — A single Sentinel-2 multispectral image covering a 100km x 100km area is 100-500MB of raw data. Downloading and displaying this on a mobile device is impractical — it would take minutes to download and crash most devices trying to render it. Fix: Always use the tile server endpoints provided by Earth Engine (getMapId returns tile URLs), Sentinel Hub (tile URLs via WMTS/XYZ endpoint), or NASA (tile service). These return 256x256 PNG tiles of just the visible map area, typically 10-50KB each, and load instantly on mobile.
- **Putting Google Earth Engine API credentials directly in FlutterFlow Custom Code** — Earth Engine service account JSON keys grant full access to your Google Cloud project's Earth Engine quota. Embedding them in the compiled app means anyone who decompiles the app can extract and abuse your credentials, incurring costs and usage against your project. Fix: All Earth Engine calls must be made from Cloud Functions using the service account credentials stored as Cloud Function environment secrets. FlutterFlow calls your Cloud Function, which calls Earth Engine — the credentials never leave the server.
- **Re-fetching satellite tile URLs on every map interaction (pan, zoom)** — Earth Engine tile URL generation takes 2-5 seconds per request. If you call getNDVITiles every time the user pans the map, the app becomes unusable — every pan triggers a 2-5 second delay before the new tiles load. Fix: Cache the tile URL in Page State when the date range changes. The Google Maps tile system automatically fetches individual 256x256 tiles for the visible viewport — you only need to update the tile URL template when the user changes the date range or data layer, not on every pan or zoom.

## Best practices

- Always display a color legend alongside satellite data overlays — NDVI values or AQI index numbers are meaningless without a reference scale with labels
- Add a data source attribution text (e.g., 'Data: NASA/USGS Landsat 9, processed via Google Earth Engine') to comply with open data licensing requirements
- Use Google Earth Engine's filterDate and filterBounds parameters to limit processing to the date range and geographic area the user is actually viewing
- Cache processed tile URL results in Firestore with a TTL — NDVI for a given month does not change, so there is no need to re-process the same query twice
- Show a CircularProgressIndicator while Earth Engine processes the request — the 2-5 second wait is normal and users need to know the app is working
- Test on physical devices — satellite map overlays with large tile sets can expose memory issues on older Android devices that are not visible in FlutterFlow's preview
- For production apps with many users, consider pre-generating monthly NDVI tiles and storing the tile URLs in Firestore to avoid per-user Earth Engine processing costs

## Frequently asked questions

### Is Google Earth Engine free to use?

Google Earth Engine is free for non-commercial research and education after completing an access request at signup.earthengine.google.com (approval typically takes 1-3 days). Commercial applications require a commercial license — pricing is based on usage. For a small FlutterFlow app, costs are minimal. Satellite processing is billed per CPU second; a typical NDVI tile request costs approximately $0.001. For production commercial apps, budget $10-100/month depending on user count and query frequency.

### Which satellite API should I use for my environmental monitoring app?

NASA FIRMS for fire data (free, no processing required). Google Earth Engine for vegetation index (NDVI), land surface temperature, and complex analysis (free for non-commercial). Sentinel Hub for higher resolution land cover and true-color imagery (paid, from 25 euros/month). MapBox Satellite for a high-quality satellite basemap behind your data overlays (free tier available). Start with NASA FIRMS and MapBox as they require the least setup, then add Earth Engine for analysis layers.

### How current is satellite imagery in these APIs?

NASA FIRMS fire data: near real-time, 3-6 hours after satellite pass. Google Earth Engine Landsat 9: 16-day revisit cycle, latest imagery typically 1-4 weeks old (processed into cloud-free composites). Sentinel-2: 5-10 day revisit cycle, similar freshness to Landsat. For truly current imagery (same day), commercial providers like Planet Labs or Maxar are needed but cost significantly more.

### Can I let users draw an area on the map and get environmental data for that polygon?

Yes. Use a polygon drawing Custom Widget (add flutter_google_maps_draw or implement a tap-to-create-polygon Custom Widget). Store the user's drawn polygon as a list of GeoPoints in Page State. Send the polygon coordinates to your Cloud Function, which uses it as a filterBounds polygon for Earth Engine queries. Return aggregate statistics (average NDVI, total burned area) for the drawn region as well as the tile overlay.

### What map projections do these satellite APIs use?

All APIs referenced in this tutorial return data in EPSG:4326 (WGS84 latitude/longitude) or EPSG:3857 (Web Mercator) — the same projections used by Google Maps and MapBox. No coordinate conversion is needed for display. When working with GeoPoints in Firestore for geographic filtering or distance calculations, use EPSG:4326 (standard latitude/longitude decimal degrees).

---

Source: https://www.rapidevelopers.com/flutterflow-tutorials/how-to-integrate-satellite-imagery-for-environmental-monitoring-in-flutterflow
© RapidDev — https://www.rapidevelopers.com/flutterflow-tutorials/how-to-integrate-satellite-imagery-for-environmental-monitoring-in-flutterflow
