Databuckets Event Tracker SDK for Flutter

Lightweight analytics SDK for Flutter apps. Automatic event tracking, session management, and batched event delivery with SQLite storage and NDJSON format.


1. Setup

a. Add dependency

dependencies:
  databuckets_event_tracker: ^2.0.0
flutter pub get

b. Android configuration

No additional configuration needed. The SDK plugin registers automatically via Flutter's plugin system.

Minimum requirements: Android SDK 21+, compileSdk 33.

c. iOS configuration

No additional configuration needed. Add to your Podfile if not already present:

platform :ios, '11.0'

2. Initialize SDK

Call initialize() early in your app's lifecycle (e.g., in main() or initState()):

import 'package:databuckets_event_tracker/databuckets_event_tracker.dart';

final config = DatabucketsEventTrackerConfigBuilder(
  apiKey: 'your-api-key',
  baseUrl: 'https://your-endpoint.com',
)
  .setFlushThreshold(500)        // Flush when 500 events are queued
  .setMaxEventsStored(50000)     // Max events stored locally
  .setFlushInterval(10000)       // Flush every 10 seconds (ms)
  .setMaxFlushSizeKB(256)        // Max flush payload 256 KB
  .build();

await DatabucketsEventTracker.initialize(config);

Configuration parameters

Parameter Description Default
flushThreshold Send events when queue reaches this count 500
maxEventsStored Maximum events stored locally (SQLite + memory) 50,000
flushInterval Periodic flush interval (ms) 10,000 (10s)
maxFlushSizeKB Max HTTP payload size per batch (KB) 256

3. Record Events

Basic event

await DatabucketsEventTracker.record('button_click', {
  'button_id': 'purchase_btn',
  'screen': 'shop',
});

Event with timing

Calculate duration between two events:

// Record start event
await DatabucketsEventTracker.record('level_start');

// ... later, record end event with duration from start
await DatabucketsEventTracker.recordWithTiming(
  'level_complete',            // event name
  {'level': 5, 'score': 1200}, // params (optional)
  'duration_ms',               // timing property name
  'level_start',               // start event to measure from
);

Common properties

Properties attached to all subsequent events:

await DatabucketsEventTracker.setCommonProperties({
  'level': 1,
  'progress': 0.99,
});

// Or set a single property
await DatabucketsEventTracker.setCommonProperty('player_name', 'Alice');

Advanced: Event object

import 'package:databuckets_event_tracker/model/event.dart';

Event event = await Event.create('purchase');

event.setEventParams({'product_id': 'sku_5678', 'price': 49.99});
event.addEventParams({'currency': 'USD'});
event.addUserProperties({'membership': 'premium'});

await DatabucketsEventTracker.addEvent(event);

4. Exception Tracking

// Enable — captures uncaught Flutter and platform errors
DatabucketsEventTracker.enableExceptionLogTracking();

// Disable
DatabucketsEventTracker.disableExceptionLogTracking();

5. Stop & Resume

DatabucketsEventTracker.stop();    // Pause sending (events still stored locally)
DatabucketsEventTracker.resume();  // Resume sending

6. Flush

Force an immediate flush of queued events:

await DatabucketsEventTracker.flushNow();

7. Automatic Events

Event Description
first_open First app open after install. Always emitted once per install attempt and includes first_open_install_diff_ms plus first_open_install_within_window (1 inside the install window, 0 outside). Delivery-confirmed via HTTP 200.
session_start New session started (30-minute inactivity timeout).
app_focus_end App moved to background. Includes app_focus_duration in milliseconds.
app_exception_log Uncaught exception (when exception tracking is enabled).

Session management

  • Sessions auto-start on first event or after 30 minutes of inactivity.
  • session_id format: {user_pseudo_id}:{session_start_timestamp}
  • session_number increments per new session.
  • session_progress = seconds elapsed since session start.

8. Default Event Properties

Every event automatically includes:

Property Type Example
event_date int 20250505
event_local_day_of_week String "1 - Monday"
event_local_hour int 11
event_local_hour_minute int 1106
install_day int 20250415 or -1
retention_day int 20 or -1
retention_hour int 480 or -1
retention_minute int 28800 or -1
session_id String "db-xxxx:1746417808764"
session_progress int 170
session_number int 5
user_pseudo_id String "db-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
sdk_ver String "2.0.0"
sdk_ver_num int 200
engagement_time_msec int 3500

install_day is best-effort. If the native install-time lookup times out, fails, or returns an invalid value and the SDK has no valid cached install timestamp yet, the emitted event uses install_day = -1. In that same state, retention_day, retention_hour, and retention_minute are also emitted as -1.

User properties (auto-collected)

Property Type Example
geo Map<String, dynamic> {"country":"VN"}
app_platform String "android"
app_store String? null on Android, "App Store" on iOS
app_version String "1.0.0"
app_id String "com.example.myapp"
device Map<String, dynamic> {"brand_name":"google","model":"Pixel 7","platform_version":"14","user_default_language":"en-US","timezone_offset_seconds":25200,"category":"mobile","id":"7a349ab563648412","is_limited_ad_tracking_enabled":false,"resettable_id":"6b6d4c6f-..."}
ip_country_code String "VN"
appid String "com.example.myapp"
platform String "android"

Serialized NDJSON payloads keep geo and device as nested top-level objects. The runtime does not emit dotted keys such as geo.country or device.brand_name.


9. Pre-init Event Buffering

Events recorded before initialize() completes are buffered (up to 200 normal events, 1000 for critical events like first_open, session_start, ad_impression). They are automatically drained after initialization.


10. Storage

  • Primary: SQLite with WAL mode (up to maxEventsStored events).
  • Fallback: In-memory queue (500 events) if SQLite is unavailable.
  • Format: NDJSON (newline-delimited JSON) with Content-Type: application/x-ndjson.
  • SQLite-backed events persist across app restarts until successfully sent (HTTP 200).
  • If SQLite is unavailable and the SDK is using the in-memory fallback queue, those fallback events are not restart-durable and can be lost on app restart.

11. Notes

  • user_pseudo_id is auto-generated as "db-" + UUID v4 on first launch and persisted.
  • No Firebase dependency required.
  • SDK does not block the main thread — all I/O is async.
  • Geo info (IP country code) is fetched asynchronously and does not block event sending.