Skip to Content

Firebase Realtime Database Adapter

The tracelet_firebase package provides a seamless, drop-in adapter to sync your background locations directly to the Firebase Realtime Database (RTDB) — 100% serverless, with no Cloud Functions to deploy.

Installation

Add the adapter to your pubspec.yaml:

flutter pub add tracelet_firebase

This adapter uses firebase_core and firebase_auth. You must configure your Flutter app for Firebase (using flutterfire configure) and create a Realtime Database in the Firebase console before using it.

How it Works

Unlike a Firestore SDK integration, this adapter does not open a separate write path. It plugs into Tracelet’s battery-efficient native HTTP sync engine: buildHttpConfig produces an HttpConfig pointing at your RTDB’s REST endpoint (<database>/<path>.json), authenticated with the Firebase Auth ID token as the ?auth= query parameter.

Because syncing runs in the native engine, batches are uploaded with exponential backoff and offline queuing even when the app is force-quit. When a token expires and the RTDB returns 401, configureTokenRefresh transparently refreshes the Firebase ID token — in the foreground and in a headless background isolate — and retries.

Setup & Configuration

Initialize Firebase

Initialize Firebase in your main.dart before calling Tracelet:

import 'package:firebase_core/firebase_core.dart'; import 'firebase_options.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); runApp(const MyApp()); }

Configure token refresh & build the HTTP config

Call configureTokenRefresh() once, then build the HttpConfig for your RTDB path and pass it to Tracelet.ready:

import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:tracelet_firebase/tracelet_firebase.dart'; import 'package:tracelet/tracelet.dart'; // 1. Your Realtime Database URL (from FirebaseOptions). final databaseUrl = Firebase.app().options.databaseURL; // 2. Keep the Firebase ID token fresh in the background (resolves 401s). await TraceletFirebase.configureTokenRefresh(); // 3. Get the signed-in user's id for a per-user write path. final uid = FirebaseAuth.instance.currentUser?.uid ?? 'anonymous_device'; // 4. Build the native HTTP config for RTDB. final httpConfig = await TraceletFirebase.buildHttpConfig( databaseUrl: databaseUrl!, // e.g. https://my-project-default-rtdb.firebaseio.com path: 'locations/$uid', // secure this path in your RTDB rules // autoSync: true, batchSync: true, maxBatchSize: 250 are the defaults ); // 5. Start Tracelet with the adapter's HTTP config. await Tracelet.ready(Config( geo: const GeoConfig(distanceFilter: 50), http: httpConfig, )); await Tracelet.start();

The user must be authenticated for the write to succeed against secured rules. If you don’t have a real sign-in flow yet, FirebaseAuth.instance.signInAnonymously() is enough to get a uid while testing.

Attaching custom metadata

To tag every location with business data (e.g. an order_id or trip_id), use setRouteContext() — it travels with each location through the SQLite queue and is included in the RTDB payload:

await Tracelet.setRouteContext(RouteContext( taskId: 'order_123', custom: {'trip_id': 'trip_456'}, ));

Security Rules

Secure your Realtime Database so authenticated users can only write to their own location path:

{ "rules": { "locations": { "$uid": { ".read": "auth != null && auth.uid === $uid", ".write": "auth != null && auth.uid === $uid" } } } }