Flutter SDK

Dart · Flutter 3.10+ · Material 3

Overview

The Avafli Engagement SDK lets you add daily-entry sweepstakes and prize experiences to your app with a single configuration call. The SDK automatically opens the experience on the first app-open of each day, captures the user, and claims their daily entries — no scheduling or session logic on your side. You customize your logo, prize image, and brand color from the Avafli dashboard; everything else is managed server-side.

Requirements

Flutter3.24+
Dart3.5+
PlatformiOS 13+ / Android API 21+
Publisher API KeyContact info@avafli.com

Installation

Add to pubspec.yaml

Add the dependency to your pubspec.yaml:

dependencies:
  avafli_sdk: ^3.2.0

Then install the package:

flutter pub get

Quick Start

One call at app launch is the entire integration:

main.dart
import 'package:avafli_sdk/avafli_sdk.dart';

await Avafli.configure(AvafliConfiguration(
  apiKey: 'YOUR_API_KEY', // debug builds: use your avafli_test_ sandbox key
  bundleId: 'com.example.myapp',
  autoOpen: AvafliAutoOpen.always,  // or .returningUsersOnly / .never
  user: AvafliUser(
    id: 'user_123',             // only id is required — pass whatever identity you have
    firstName: 'Jane',
    lastName: 'Doe',
    email: 'jane@example.com',  // include it when you have it — pre-fills & locks the capture form
  ),
  // Nobody signed in? use user: AvafliUser.guest
  options: AvafliOptions(
    logging: LoggingLevel.error,  // LoggingLevel.debug while integrating
    enablePushReminders: true,    // then forward tokens: Avafli.registerPushToken(token)
  ),
));

// Attach the navigator key: MaterialApp(navigatorKey: Avafli.navigatorKey, ...)
// Done — auto-opens once a day. To open it yourself: Avafli.present()

By default the experience opens itself on the first app-open of each day, once you attach the SDK’s navigator key (MaterialApp(navigatorKey: Avafli.navigatorKey)) — presentation timing, the daily cadence, and dismissal are managed by the SDK. When your app needs to decide the moment, use the controls below.

Controlling when the drawer opens

The default is unchanged: the drawer opens itself once a day on app open. Three controls change that when you need to:

  • autoOpen on the configuration — AvafliAutoOpen.always (default), AvafliAutoOpen.returningUsersOnly, or AvafliAutoOpen.never. AvafliAutoOpen.returningUsersOnly keeps the drawer out of a first-time user's onboarding: it skips the auto-open on the launch where the device is first registered, then auto-opens normally on every later launch. AvafliAutoOpen.never means the SDK never auto-opens and you call Avafli.present().
  • Avafli.present() — open the drawer from a button, a screen, or an onboarding-complete handler. It ignores the once-a-day rule and the impression cap, waits for registration if it is still in flight, and no-ops if the drawer is already open or the user has opted out. Returns true when the drawer was shown, false when there is nothing to show (no active giveaway, opted out, registration failed) — it never throws for these.
  • Avafli.holdAutoOpen() / Avafli.releaseAutoOpen() — for boot flows. Call Avafli.holdAutoOpen() before configuring to defer the daily auto-open (nothing is burned — no once-a-day mark, no impression), and Avafli.releaseAutoOpen() once your main screen is ready; it re-runs the eligibility check immediately. Use this when your splash screen or auth gate ends by clearing the navigation stack (Get.offAll, pushAndRemoveUntil), so the drawer isn't destroyed by your boot navigation. Avafli.present() still works while held.
await Avafli.configure(AvafliConfiguration(
  apiKey: 'YOUR_API_KEY',
  bundleId: 'com.example.myapp',
  user: AvafliUser(id: 'user_123'),
  autoOpen: AvafliAutoOpen.never, // always (default) | returningUsersOnly | never
));

// Later — e.g. from your onboarding-complete handler
Future<void> onOnboardingComplete() async {
  final shown = await Avafli.present(); // false if no active giveaway or opted out
}

Registration and analytics (DAU/MAU) run on configure regardless of mode.

Push Notifications

Drive re-engagement with daily reminders. Forward your FCM token to the SDK:

import 'package:firebase_messaging/firebase_messaging.dart';

// Get the FCM token and forward it to Avafli
final fcmToken = await FirebaseMessaging.instance.getToken();
if (fcmToken != null) {
  await AvafliPushNotificationManager.instance.didReceiveRegistrationToken(fcmToken);
}

// Listen for token refreshes
FirebaseMessaging.instance.onTokenRefresh.listen((token) {
  AvafliPushNotificationManager.instance.didReceiveRegistrationToken(token);
});

Upload your FCM service account key via the Avafli Dashboard to enable push notifications.

Branding

Branding is configured server-side — no code changes needed. Publishers customize three things — their logo, the prize image, and their primary brand color — via the Customize Experience section in the publisher dashboard. Everything else is designed and managed by Avafli. Changes take effect immediately in the SDK.

Analytics

Connect your analytics system to track user engagement:

class MyAnalyticsAdapter implements AnalyticsAdapter {
  @override
  void track(String eventName, [Map<String, dynamic>? parameters]) {
    // Forward to Segment, Amplitude, Mixpanel, etc.
    analytics.track(eventName, parameters);
  }

  @override
  void setUserProperty(String name, String value) {
    analytics.setUserProperty(name, value);
  }

  @override
  void identify(String userId) {
    analytics.identify(userId);
  }
}

// Pass during configuration
await Avafli.configure(AvafliConfiguration(
  apiKey: 'YOUR_API_KEY',
  bundleId: 'com.example.myapp',
  user: AvafliUser(id: 'user_123'),
  options: AvafliOptions(
    analyticsAdapter: MyAnalyticsAdapter(),
  ),
));

Account deletion in your app

If your app has its own delete-account flow, call optOut() from it so the user's Avafli data is erased along with their account. Users can also delete their data themselves at any time from the Privacy Policy screen inside the experience — no integration required.

// From your delete-account flow
await Avafli.optOut();

Testing? Your dashboard also shows a avafli_test_ sandbox key. Use it in debug builds: identical behavior against the production backend, but users and entries land in an isolated sandbox — your testers can never enter your real giveaway.

SDK Features

Escalating Streak Ladder with Milestone Accelerators
Daily or Visit-Based Streak Modes
Winner Announcements & Celebrations
Auto-Open on First Daily App-Open
Email Capture & Age Gate (18+)
Push Notifications (FCM)
Server-Driven Configuration
GDPR Compliance
Offline Resilience
Built-in Analytics Support
Custom Logo, Prize Image & Brand Color
Cross-platform (iOS/Android)

Full API Reference & Code Examples

View the complete documentation on GitHub including API reference, code examples, and advanced configuration.