Skip to main content

apprvd_tracker 0.6.0 copy "apprvd_tracker: ^0.6.0" to clipboard
apprvd_tracker: ^0.6.0 copied to clipboard

Tiny event tracker for Apprvd.app. Batches events in memory and posts them to Apprvd.app's ingest endpoint for push audiences and tracker KPIs.

apprvd_tracker #

Tiny event tracker for Apprvd.app. Events post straight to Apprvd.app and show up on the dashboard in real time. They power push audiences and tracker KPIs; the charts come from Google Analytics. Pure Dart, one dependency (http).

Setup #

In Apprvd.app: Data sources → Apprvd.app tracker → Connect source, then copy the generated write key (it's write-only, so safe to ship in the binary).

dependencies:
  apprvd_tracker: ^0.6.0
import 'package:apprvd_tracker/apprvd_tracker.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:package_info_plus/package_info_plus.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final info = await PackageInfo.fromPlatform();
  Apprvd.init(
    writeKey: 'pk_…',
    endpoint: 'https://…/api/ingest', // from the Data sources page
    deviceId: yourStableInstallId, // recommended: accurate unique counts
    platform: kIsWeb ? 'web' : defaultTargetPlatform == TargetPlatform.iOS ? 'ios' : 'android',
    appVersion: info.version, // e.g. '2.4.1'
  );
  Apprvd.track('app_open');
}

platform ('ios', 'android' or 'web') and appVersion are optional: the tracker is pure Dart and can't read them itself, so pass what your app already has (package_info_plus above). With them, Apprvd.app compares each release with the one before and flags a key event that stopped arriving on the new version, such as sign-ups that broke in 2.4.1. Each batch also carries the SDK's own version, Apprvd.sdkVersion.

Apprvd.identify(user.id);                          // after sign-in
Apprvd.track('lesson_completed', {'lesson': 'intro', 'score': 87});
await Apprvd.flush();                              // e.g. when backgrounded

Flushing when a Flutter app is backgrounded:

class FlushOnPause extends WidgetsBindingObserver {
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.paused) Apprvd.flush();
  }
}
// in main(): WidgetsBinding.instance.addObserver(FlushOnPause());

Experiments #

Run an A/B test without Firebase Remote Config. Your code holds the variants; Apprvd.app decides which one each device gets and counts the results.

// The app knows both versions; Apprvd only says which one this device gets.
final copy = Apprvd.variant('paywall_copy', fallback: 'long');

Widget paywall() => switch (copy) {
      'short' => const ShortPaywall(), // the version being tested
      _ => const LongPaywall(),        // 'long', and the fallback if anything fails
    };

Apprvd.track('trial_start'); // the goal event the test is measured on
  • Create the test in Apprvd.app: Start a change → Test first → Apprvd SDK, with the same key and variant names. The first variant is the control: pass it as fallback.
  • Apprvd sends only which tests are live, their variant names and weights, and each decided test's winner, never values or results.
  • Start, stop and ship from Apprvd.app, with no app update. A decided test serves its winner to everyone; a key with no live test returns the fallback.
  • The same device always gets the same variant: a stable hash of the device id and the test, so pass a stable deviceId.
  • One answer per session. The first answer for a key holds until the next launch, so a screen never flips while someone is on it.
  • Exposures. The first assigned answer in a session sends an apprvd_exposure event (fallbacks and winners don't). Results count the devices exposed to each variant that send the goal event afterwards, with no Remote Config parameter and no Google Analytics custom dimension.

The config is fetched at init. Save it, so a returning user gets their variant from the first frame. On a first launch, wait briefly for it:

final prefs = await SharedPreferences.getInstance();
Apprvd.init(
  writeKey: 'pk_…',
  endpoint: 'https://…/api/ingest',
  deviceId: yourStableInstallId,
  experimentsCache: prefs.getString('apprvd_experiments'),
  onExperiments: (json) => prefs.setString('apprvd_experiments', json),
);
await Apprvd.experimentsReady; // done on the first answer, or after 2 s

A key asked for before any config arrived gets its fallback for that session and isn't counted. configEndpoint: overrides where the config comes from (it defaults to sdk/config next to the ingest URL).

Rules of the road #

  • Event names: letters, digits, underscores, max 60 chars (lesson_completed).
  • Params must stay under 8 KB as JSON, and don't put personal data in them.
  • Events batch in memory (20 per flush, every 10 s) and retry on network errors. The queue caps at 500 and does not survive an app restart.
  • Without a stable deviceId/identify, unique counts inflate: each launch looks like a new device.
0
likes
160
points
531
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Tiny event tracker for Apprvd.app. Batches events in memory and posts them to Apprvd.app's ingest endpoint for push audiences and tracker KPIs.

Homepage

License

MIT (license)

Dependencies

http

More

Packages that depend on apprvd_tracker