Moving Beyond thee Basics: Why Real- Time Location Matters

User location is one of thee most powerful data streams a mobile application can capture. When done right, it turns a static app into a context-aware tool that anticipates what users need. React Native Maps combined with the Geolocation API ithe industriystand approach for this, and they integrate naturally with a headless CMS like Directus. By storing and serviting location data directug, you cave build ureging fror tracking.

Architecture Overview: Where Directus Fits In

Before writing any code, it helps to understand how the piece connect. React Native handles the mobile frontend, including ding map rendering and raw location data. Directus acts as the backend and headless CMS. It stores user location historie, geofence definitions, and any metadata you need. Thee React Native app fetches and sends location data to Directus via its REST or GraphQL API. This separation keeps your fronr tend leaann your datáglized, search chable, and auditable.

For a deeper look at Directus 's data modeling capabilities, see the indiv1; indiv1; FLT: 0 condiv3; indiv3; Directus Data Modeling Guide indiv1; indiv1; FLT: 1 condiv3; indiv3;.

Prerequisites andPackage Setup

You 'll need a working React Native project (CLI or Expo bare workflow) anda Directus instance. For local development, you can spin up Directus via Docker. Here are te te cre packages you need in your React Native project:

  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; react- nativ- maps Xiv1; Xiv1; FLT: 1 Xiv3; Xiv3; Xiv3d3; Xivymmp; ndash; Provides the map Xivient andd marker overlay.
  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; @ react- nativ- community / geolocation Xiv1; Xiv1; FLT: 1 Xiv3; Xiv3; Ximp; ndash; Access to device GPS and network location.
  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; @ react- nativ- community / geolocation Xiv1; Xiv1; FLT: 1 Xiv3; Xiv3; Ximp; ndash; Access to device GPS and network location.

Zainstaluj ten projekt:

npm install react-native-maps @react-native-community/geolocation

For iOS, run indi1; indi1; FLT: 1 supporte3; endi3; to link the nativa modules. If you 're using Expo, you will need to eject to the bare workflow or use thee use the 1.; entil 1; fLT: 2 contributee 3; condition 3; because these libraries require nativa module linking. After installation, verify everything compiles by running thee app on a simulator odvice before moving on.

Platform Permissions: Thee Gatekeeper

Both Android and iOS require explire explict user consent to accessions location. Infaling to handle permissions gracefuly is the number one cause of runtime crashes and negative reviews. Start wigh the required platform configuation.

Konfiguracja Androida

Open aspect 1; Xion1; FLT: 3 XI3; Xion3; and add these permissions inside the he Xion1; Xion1; FLT: 4 XI1; Xion3; FLT: block, before the Xion1; Xion1; FLT: 5 XIon3; Xion3; element:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Xi1; Xi1; FLT: 7 XI3; XI3; gives GPS closacy, while XI1; XI1; FLT: 8 XI3; XI3; provides a fallback using Wi- Fi andd cell towers. Including both lets your app degrade gracefully in environments where GPS is sleek, such as indoors.

Konfiguracja iOS

Open present 1; Event 1; FLT: 9 presenta3; Eventa3; and add one e or both of these keys:

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs your location to show nearby services and track your route.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs background location access to provide continuous route tracking.</string>

Avoid generic strings like emph; ldquo; Your app neds accords to your location, hackmp; rdquo; as reviewers may reject it. Be specific: emp1; Imp1; FLT: 0 3; Imps 3; Impf: Imph; Imph; Imph; Imph: Emph; Imph: 1; Imph: 3way; Imph; Imph; Imph: 3way; Imph example.

Runtime Permission Handling in React Native

Setting manifest values is only half the work. You also need to request permission at runtime, especially on Android 6.0 + and iOS 8.0 +. Use the eg 1; eng.1; FLT: 12 need two require 3; module for Android and rely on thee nativa geocation library for iOS, which triggers the system prompant automaticall u ycall 1; EDF: 1EDF: 3; EDF 3OR; EDF; EDF 1EDF; EDF; 1; EDT: 1EDF: 1EDF; EDF: 1EDF 33D; FLT: 1EDF;

Here is a reusable permission hook:

import { PermissionsAndroid, Platform } from 'react-native';

const requestLocationPermission = async () => {
 if (Platform.OS === 'android') {
 const apiLevel = Platform.Version;
 if (apiLevel < 23) {
 // permissions granted automatically at install time
 return true;
 }
 const granted = await PermissionsAndroid.request(
 PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
 {
 title: 'Location Permission',
 message: 'This app needs access to your location.',
 buttonPositive: 'Grant',
 buttonNegative: 'Deny',
 }
 );
 return granted === PermissionsAndroid.RESULTS.GRANTED;
 }
 // iOS handles runtime permission via the Geolocation call itself
 return true;
};

Call this function before any geolocation call. If thee user denies, display a friendly message explaing the impact and offer a button to open system settings. Never simple crash or show a blank map.

Core Implementation: Displaying the User on a Map

With permissions wired up, you can build the main tracking contrigent. The following code requests the user 's current position, sets the map region, and drops a marker. It also updates the marker in real time using present 1; Ig1; FLT: 16 memorial 3; Ig3;

import React, { useState, useEffect, useRef } from 'react';
import { View, StyleSheet } from 'react-native';
import MapView, { Marker, PROVIDER_GOOGLE } from 'react-native-maps';
import Geolocation from '@react-native-community/geolocation';
import { requestLocationPermission } from './permission';

const LocationTracker = () => {
 const [region, setRegion] = useState(null);
 const [currentLocation, setCurrentLocation] = useState(null);
 const watchId = useRef(null);
 const mapRef = useRef(null);

 useEffect(() => {
 const initTracking = async () => {
 const hasPermission = await requestLocationPermission();
 if (!hasPermission) return;

 // Get the initial position immediately
 Geolocation.getCurrentPosition(
 (position) => {
 const { latitude, longitude } = position.coords;
 const initialRegion = {
 latitude,
 longitude,
 latitudeDelta: 0.01,
 longitudeDelta: 0.01,
 };
 setRegion(initialRegion);
 setCurrentLocation({ latitude, longitude });
 },
 (error) => {
 console.warn('Initial position error:', error.message);
 },
 { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
 );

 // Subscribe to continuous updates
 watchId.current = Geolocation.watchPosition(
 (position) => {
 const { latitude, longitude } = position.coords;
 setCurrentLocation({ latitude, longitude });
 // Optionally animate the map to follow the user
 mapRef.current?.animateToRegion({
 latitude,
 longitude,
 latitudeDelta: 0.01,
 longitudeDelta: 0.01,
 }, 500);
 },
 (error) => {
 console.warn('Watch position error:', error.message);
 },
 { enableHighAccuracy: true, distanceFilter: 10, interval: 5000 }
 );
 };

 initTracking();

 return () => {
 if (watchId.current !== null) {
 Geolocation.clearWatch(watchId.current);
 }
 };
 }, []);

 if (!region) {
 return ;
 }

 return (
 
 
 {currentLocation && (
 
 )}
 
 
 );
};

const styles = StyleSheet.create({
 container: { flex: 1 },
 map: { flex: 1 },
});

export default LocationTracker;

Key szczegółowo opisuje implementation:

  • Xi1; Xi1; FLT: 0 Xi3; Xi3; distanceFilter: 10 Xi1; Xi1; FLT: 1 Xi3; Ximp; ndash; Only triggers a location update whene thee device moves at least 10 meters. This saves battery andd reduces network calls.
  • Xi1; Xi1; FLT: 0 Xi3; Xi3; interval: 5000 Xi1; Xi1; FLT: 1 Xi3; Ximp; ndash; Caps the update frequency to o once every 5 seconds on Android. iOS ignores this but uses its own throttling.
  • Xi1; Xi1; FLT: 0 X3; Xi3; showsUserLocation Xi1; Xi1; FLT: 1 XI3; XIMM-; NDASH; A built- in React Native Maps Xicure that displays a nativie system dot for the user 's location, even with oun explicit marker. It also handles the blue pulsing creacy circle.

Persisting Location Data tu Directus

Displaying thee location on a map is useful, but te real value comes from storing and querying that data. In Directus, create a collection called British 1; Ig1; FLT: 0 British 3; Iglomeration; FLT: 1 British 3; FLT: 1 British 3; Iglomerate; With these Fields:

  • Xi1; Xi1; FLT: 0 Xi3; Xi3; id Xi1; Xi1; FLT: 1 Xi3; Xi3; (auto- increment, primary key)
  • (sring or relation to directus _ users)
  • Xi1; Xi1; FLT: 0 Xi3; Xi3; laxidde Xi1; Xi1; FLT: 1 Xid3; Xid3; (float)
  • Xi1; Xi1; FLT: 0 Xi3; Xi3; Xi1; Xi1; FLT: 1 Xi3; Xi3; (float)
  • Xi1; Xi1; FLT: 0 Xi3; Xi3; Xi1; FLT: 1 Xi3; FLT: (float, meters)
  • Xi1; Xi1; FLT: 0 Xi3; Xi3; timestamp Xi1; Xi1; FLT: 1 Xi3; Xi3; (datetime, auto- generated)

Then, inside your indi1; indi1; FLT: 18 indirec3; indirec3; callback, send each update to Directus:

import axios from 'axios';

const DIRECTUS_URL = 'https://your-directus-instance.com';
const DIRECTUS_TOKEN = 'your-static-token-or-dynamic-jwt';

const saveLocationToDirectus = async (coords) => {
 try {
 await axios.post(
 `${DIRECTUS_URL}/items/locations`,
 {
 latitude: coords.latitude,
 longitude: coords.longitude,
 accuracy: coords.accuracy,
 // user_id is typically pulled from auth context
 },
 {
 headers: {
 Authorization: `Bearer ${DIRECTUS_TOKEN}`,
 },
 }
 );
 } catch (error) {
 console.error('Failed to save location:', error.response?.data || error.message);
 }
};

Batch updates if you oczekuje high- frequency writes. Directus supports creating multiple items at once by passing an array to the same endpoint. This reduces network overhead andd avoids rate limits.

Geofencing wigh React Native andDirectus

Geofencing is thee ability to detect wheren a user enters or exit a predefinied geographic boundary. Directus can story these boundary definitions, and your r React Native app cat check them against thee concurt position. This Pattern powers notifications like indemps; ldquo; Welcome te store! indempmpt; rdquo; or consempt them againdempt; ldquo; You left yourt officie area.

Storing Geofelece in Directus

Stworzenie kolektyonu called amend1; EDI1; FLT: 0 EDI3; EDI3; geofeleres presend1; EDI1; FLT: 1 EDI3; EDI3; with the following fields:

  • Xi1; Xi1; FLT: 0 Xi3; Xi3; id Xi1; Xi1; FLT: 1 Xi3; Xi3; (primary key)
  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; name Xiv1; Xiv1; FLT: 1 Xiv3; Xiv3; (string)
  • Xi1; Xi1; FLT: 0 Xi3; Xi3; laxidde Xi1; Xi1; FLT: 1 Xid3; Xid3; (float)
  • Xi1; Xi1; FLT: 0 Xi3; Xi3; Xi1; Xi1; FLT: 1 Xi3; Xi3; (float)
  • GR1; GR1; GR3; GR3; GR1; GR1; GR3; GR3; (float, methers)
  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; xigger _ on _ entry Xiv1; Xiv1; FLT: 1 Xiv3; Xiv3; (booleun)
  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; xigger _ on _ exit Xiv1; Xiv1; FLT: 1 Xiv3; Xiv3; (booleun)
  • Xi1; Xi1; FLT: 0 Xi3; Xi3; message Xi1; Xi1; FLT: 1 Xi3; Xi3; (text)

Klient - Side Geofence Check

On each location update, fetch the active geofeles from Directus and teste distance thee contect position and each fence center. You can use thee Haversine formula or a simpler approximation:

const getDistanceFromLatLonInMeters = (lat1, lon1, lat2, lon2) => {
 const R = 6371000; // Earth's radius in meters
 const dLat = (lat2 - lat1) * Math.PI / 180;
 const dLon = (lon2 - lon1) * Math.PI / 180;
 const a =
 Math.sin(dLat / 2) * Math.sin(dLat / 2) +
 Math.cos(lat1 * Math.PI / 180) *
 Math.cos(lat2 * Math.PI / 180) *
 Math.sin(dLon / 2) *
 Math.sin(dLon / 2);
 const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
 return R * c;
};

const checkGeofences = async (currentCoords, geofences) => {
 for (const fence of geofences) {
 const distance = getDistanceFromLatLonInMeters(
 currentCoords.latitude,
 currentCoords.longitude,
 fence.latitude,
 fence.longitude
 );
 if (distance <= fence.radius) {
 return fence; // user is inside this geofence
 }
 }
 return null;
};

To jest dobre, ale nie jest dobre.

Wykonanie i Battery Optimization

Location tracking is one of thee mott battery- intensive equidures on mobile. Users will uninstall an app that drains their ir phone, so optimization is nott optional. Follow these guidelines:

  • Reference: 1; Xi1; FLT: 0 Xi3; Xi3; Usie distanceFilter Xi1; Xi1; FLT: 1 Xi3; Ximp; ndash; Set it high enough to avoid jittery updates. For walking apps, 10 meters is a good baseline. For driving apps, 20- 50 meters works better.
  • Reduction location celliacy wheden possible indiv1; Evil 1; FLT: 1 presendi1; Evidenti3; Evidenti3; Evident; Ndash; For providures like evimp; ldquo; Equirent city, evimpmp; rdquo; coarsie location (network- based) is provident. Usie fine (GPS) only whein cleacy below 50 meters matters.
  • W przypadku gdy w wyniku połączenia z siecią nie jest możliwe uzyskanie dostępu do sieci, należy podać numer telefonu.
  • W przypadku gdy w przypadku gdy nie ma możliwości, aby w przypadku gdy w danym państwie członkowskim nie ma miejsca, w którym ma miejsce zmiana, należy podać datę, w której osoba ta nie jest w stanie podjąć decyzji o zmianie, należy podać datę, w której osoba ta nie może podjąć decyzji o zmianie.
  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; Xiv3; Xiv1; FLT: 0 Xiv3; Xiv3; Xiv3; Xiv3; Xiv3; Xiv3; Xiv3; Xiv3; VYMMMM3; Xiv3; VYB3; FLT: Xiv3; XIXM3; XIX3; XIXM3; XIXMM3; X3; X3; XIX3; VEX3; VEX3; VEX3; VEYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY.

Ampie and Google both provide e detailed d energy profiling tools. Usie Xcode 's Energy Log and Android' s Battery Historian to inspect your app 's before shipping.

Error Handling andEdge Cases

Location services are notoriously unreliable. Users may deny deny permissions, airplane mode may be on, GPS may be bloked indoors, and older devices can return stale or willy inclosiate data. You r app should exprecid aste every one of these morios.

  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; Permisson denied Xiv1; Xiv1; FLT: 1 Xiv3; Xiv3; Xivmp; ndash; Show a non-blocking banner with a Ximp; ldquo; Open Settings Ximp; rdquo; button. Never force- quit thee app.
  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; Location unaclivable Xiv1; Xiv1; FLT: 1 Xiv3; Xiv3; Xiv3; FLT: 0 Xiv3; Xiv3; Xiv3; Xiv3; FLT: 1 XIX3; Xiv3; Ximp; Ndash; Display a message like Xiv3; ldquo; Location temporarily unacvavaiable. Check your device settings. Ximp; rdquo; Continue waing so the app recourtatically when the signal returns.
  • Xi1; Xi1; FLT: 0 Xi3; Xi3; Timeout Xi1; Xi1; FLT: 1 Xi3; Ximp; ndash; Retry up two three times s with excuential backoff. If it still fauls, fall back to coarsie location or thee last known position.
  • Xi1; Xi1; FLT: 0 Xi3; Xi3; Stale or cached data Xi1; Xi1; FLT: 1 Xi3; Ximp; ndash; Comparate the timestamp of thee returned position against Xi1; Xi1; FLT: 22 Xi3; Xi3. If it 's older than 60 seconds, discard it and wait for thee next update.

Integrate a lightweight logging servisie (or simply send errors to a Directus collection called indi.1; indiv1; FLT: 0 contribution 3; indiv3; location _ errors indiv1; indiv1; FLT: 1 contribution 3; endiv3;) so you can monitor real- endivord failure rates and improwise yourr logic iteratively.

Testing Across Devices andd Scenarios

Simulators are useful for quick UI iteration, but they cannot simulate real GPS behavor. Always tect on physical devices undeur varying conditions: walking, driving, inside a building, in a tunnel, and with the device in power-saving mode. Android emulators can inject mock location via the extended controls, but iOS simulators cannot emulate GPS at all for the geolocation library. Use a service like 1indiv.1; FLT: 0; 3; 3d; Locationary 1; FLT: 1; FLT: 1; 3d; direplayt 3d; 3o replaistic replaistic Gépél.

Stworzenie taskowartości tat pokrywa te sprawy:

  • Fresh install and- first-time permissoon prompt
  • Denying permissoon and then granting it later via settings
  • Rapid movement (driving at highway speeds)
  • Stationary device wigh high closiacy (should produce a incript cluster of points)
  • Background-to-nearround transition (did the map recover the lact known position?)

Privacy, Compliance, andUser Truss

Location data is sensitiva. Mishandling it can lead to regulatory fines and loss of user truss. Treet it with the same cre as passwords or financial information.

  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; Xiv3; Xiv1; FLT: 1 Xiv3; Xiv3; Xiv3; Ndash; Exploain exactly what location data you collect and why in your privacy policy. Link tu it frem the permissionon prompt.
  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; Data minimazation Xiv1; Xiv1; FLT: 1 Xiv3; Xiv3; Xiv3; Xivymmp; ndash; Collect only the closacy level you need. Delete old points after a retention period (for example, 30 days) via a Directus automation flow.
  • Xiv1; Xiv1; FLT: 0 Xiv3; Xiv3; Xiv3; Xiv1; FLT: 1 Xiv3; Xiv3; Ximp; ndash; Servie your Directus instance over HTTPS. Consider critipting the Xiv1; Xiv1; FLT: 23 Xiv3; Xiv3; collection fields at rest if your threat model demands it.
  • W przypadku gdy w przypadku gdy nie ma możliwości, aby w danym przypadku nie można było ustalić, czy dany podmiot jest w stanie wykazać, że jest on w stanie wykazać, że jest on w stanie wykazać, że jego działalność jest niezgodna z prawem, należy uznać, że nie istnieje żaden z tych czynników, które mogłyby mieć wpływ na jego sytuację.

For more guidance on handling personal data in Directus, review the employ1; British 1; FLT: 0 employ3; British 3; Directus Security Configuration Options; British 1; FLT: 1 employ3; British 3; British 3;.

Going Further: Advanced Use Case

Once thee basics are solid, you can layer on mone experimentate facires using thee same foundation.

Realtime Location Sharing

Usie Directus 's WebSocket or SSE support to broadcast location updates to o tequir users. For example, a delivy app can show thee courier' s moving marker on thee customer 's map. The backend receives the location via REST and pushes it out to subskrybed clients with out polling.

Lokalizacja - analizy bazowe

Aggregate location data in Directus to generate heatmaps, dwell time reports, or popular route Patterns. The Directus index1; index1; FLT: 0 index3; index3; Analytics Guidee index1; endex1; FLT: 1 index3; index3; shows how to build dashboards on top of your data.

Offline Queueing

When thee network is unaclivable, queue location points on thee device using AsyncStorage or a local database like WatermelonDB. Once connectivity resumes, flush the queue te to Directus. Thii consures data integraty even in areas witt spotty coverage.

Konkluzja

Wdrożenie serwisu location tracking with React Native Maps ande Geolocation API a well-understood paratin, but te devil is in thee details. Thy pairing a robutt frontend implementation with a headless CMS like Directus, you gain a explixed ble backend for storing, querying, and acting on location data with out building a custim API layer. Focus on on permisoon handling, battery optionin, and data privacy from the start, and you builveur deliveur ur de exeruselle d exeruselle en ful ful.