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_idformat:{user_pseudo_id}:{session_start_timestamp}session_numberincrements 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
maxEventsStoredevents). - 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_idis auto-generated as"db-" + UUID v4on 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.
Libraries
- databuckets_event_tracker
- databuckets_event_tracker_config
- handler/default_user_properties_handler
- handler/event_storage_handler
- main
- model/event
- scheduler/event_sending_scheduler
- storage/event_row
- storage/memory_event_queue
- storage/sqlite_event_storage
- tracker/auto_tracker
- tracker/engagement_tracker
- tracker/event_timestamp_tracker
- tracker/exception_tracker
- tracker/first_open_tracker
- tracker/session_helper
- utils/app_info_util
- utils/common_properties_util
- utils/device_info_util
- utils/event_date_util
- utils/event_size_util
- utils/geo_info_util
- utils/install_day_util
- utils/json_sanitizer
- utils/json_util
- utils/locale_country_util
- utils/log_util
- utils/prefs_util
- validators/event_key_validator