flutter_ads_orchestrator 0.1.0 copy "flutter_ads_orchestrator: ^0.1.0" to clipboard
flutter_ads_orchestrator: ^0.1.0 copied to clipboard

Smart AdMob orchestration for Flutter apps: preload, throttle, caps, placement rules, UMP consent. Supports interstitial and rewarded ads.

flutter_ads_orchestrator #

pub package License: MIT

Smart AdMob orchestration for Flutter — preload, throttle, consent, never spam users.

flutter_ads_orchestrator wraps google_mobile_ads 8.x with the policy layer almost every monetised Flutter app eventually has to write by hand: preload, retry/backoff, cooldown, session/day caps, placement rules, app-open guard, UMP consent, and an iOS ATT hook. One declarative config, one entry point.

Why? #

Without orchestration, an AdMob integration usually looks like this:

  • Two interstitials back-to-back because there's no global cooldown → uninstall trigger.
  • "Get reward" button taps wait 5 s for a fresh load → drop-off.
  • Forgotten preload → slow show → lost revenue.
  • Missing UMP / ATT → zero fill in EU and on iOS 14.5+.
  • Ad-show logic copy-pasted across every screen → untunable mess.

This package handles all of it through one AdsConfig.

Features #

  • Smart preload with exponential-backoff retry and a fallback ad-unit chain.
  • Throttling: cooldown, per-session cap, per-day cap (persisted).
  • Declarative placement rules: allowed, disabled, triggerEvery(N).
  • App-open guard for interstitials after cold start.
  • UMP consent integrated (GDPR / CCPA via google_mobile_ads).
  • iOS ATT callback hook — bring your own app_tracking_transparency package.
  • Sealed result types for compile-time exhaustiveness.
  • Event stream for analytics.
  • Test mode auto-overrides production ad units with Google's official test IDs.

Quick start #

import 'package:flutter/material.dart';
import 'package:flutter_ads_orchestrator/flutter_ads_orchestrator.dart';

late final AdsOrchestrator orchestrator;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  orchestrator = AdsOrchestrator(
    config: const AdsConfig(
      testMode: kDebugMode,
      interstitial: InterstitialRules(
        adUnitIds: ['ca-app-pub-xxx/yyy', 'ca-app-pub-xxx/fallback'],
        minInterval: Duration(seconds: 60),
        maxPerSession: 8,
        maxPerDay: 30,
        appOpenGuard: Duration(seconds: 30),
        placements: {
          'level_complete': PlacementRule.triggerEvery(3),
          'pause_menu': PlacementRule.disabled(),
          'game_over': PlacementRule.allowed(),
        },
      ),
      rewarded: RewardedRules(
        adUnitIds: ['ca-app-pub-xxx/zzz'],
        minInterval: Duration(seconds: 15),
      ),
    ),
  );
  await orchestrator.initialize();
  runApp(const MyApp());
}

// Anywhere in your UI:
final result = await orchestrator.showInterstitial(placement: 'level_complete');
result.when(
  shown: (id) => analytics.log('ad_shown', {'unit': id}),
  suppressed: (reason) => debugPrint('suppressed: ${reason.name}'),
  failed: (error) => debugPrint('failed: ${error.message}'),
  notReady: () => debugPrint('not preloaded'),
);

Setup #

AdMob App ID #

Add the App ID from your AdMob console (use Google's test App ID during development):

Androidandroid/app/src/main/AndroidManifest.xml inside <application>:

<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY" />

iOSios/Runner/Info.plist:

<key>GADApplicationIdentifier</key>
<string>ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY</string>

This package does not bundle an ATT plugin so non-iOS apps stay lean. If you target iOS, add app_tracking_transparency and wire the callback:

# Your app's pubspec.yaml
dependencies:
  app_tracking_transparency: ^2.0.6
import 'package:app_tracking_transparency/app_tracking_transparency.dart';

const consent = ConsentConfig(
  attRequestCallback: _requestAtt,
);

Future<bool> _requestAtt() async {
  final status = await AppTrackingTransparency.requestTrackingAuthorization();
  return status == TrackingStatus.authorized;
}

Also add to ios/Runner/Info.plist:

<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads.</string>

Placement rules #

placements: {
  // Allow every call — global rules (cooldown, caps) still apply.
  'game_over': PlacementRule.allowed(),

  // Never show at this placement.
  'pause_menu': PlacementRule.disabled(),

  // Show on every Nth call. Calls 1..N-1 return Suppressed(triggerNotMet).
  'level_complete': PlacementRule.triggerEvery(3),
},

// Unlisted placements fall back to this.
defaultPlacementBehavior: PlacementBehavior.allowed,

triggerEvery(N) is interstitial-only — rewarded ads silently ignore it since they're always user-initiated.

Event stream #

orchestrator.events.listen((event) {
  switch (event) {
    case AdLoadStartedEvent():       break;
    case AdLoadedEvent():            break;
    case AdLoadFailedEvent():        break;
    case AdShownEvent():             break;
    case AdDismissedEvent():         break;
    case AdShowFailedEvent():        break;
    case AdSuppressedEvent():        break;
    case AdExpiredEvent():           break;
    case UserEarnedRewardEvent():    break;
  }
});

Global controls #

// Premium / IAP "remove ads" — persisted via SharedPreferences.
await orchestrator.setNoAdsFlag(true);

// Re-show the UMP privacy options form (from a settings screen).
await orchestrator.showPrivacyOptions();

// Testing only:
orchestrator.resetSessionCounters();
await orchestrator.resetConsent();

// App teardown.
await orchestrator.dispose();

Comparison #

Feature google_mobile_ads alone easy_ads_flutter flutter_ads_orchestrator
Preload Manual Auto Auto
Cooldown Manual Manual Built-in
Caps per session / day Manual Manual Built-in
App-open guard Manual Manual Built-in
Placement rules Manual Manual Declarative
Fallback unit IDs Manual Manual Built-in chain
UMP integration Manual Manual Built-in
iOS ATT integration Manual Manual Hook (you pick the package)
Mediation Manual Built-in (AdMob + FAN) AdMob only

Example app #

See example/ for a minimal three-screen demo (menu / game / settings) exercising every placement rule, rewarded ads, the no-ads toggle, and the privacy options form. Run on a real device with the test ad units already configured.

Roadmap #

  • v0.2 — Banner widget, per-placement caps, debug overlay, recordEvent independent trigger counter.
  • v0.3 — Native ads inline.
  • v0.4 — App Open ads (full implementation).
  • v1.0 — Remote config hook, Riverpod / GetIt companion package.

Stability #

v0.1 is a release candidate: the pure-Dart layer (rules, counters, preload, orchestrator) has 100% line coverage; the AdMob/UMP wrappers are smoke-tested against google_mobile_ads 8.x API docs and the example app but require device validation in your environment before production rollout.

License #

MIT

1
likes
160
points
187
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Smart AdMob orchestration for Flutter apps: preload, throttle, caps, placement rules, UMP consent. Supports interstitial and rewarded ads.

Repository (GitHub)
View/report issues

Topics

#admob #ads #monetization #game-dev #consent

License

MIT (license)

Dependencies

flutter, google_mobile_ads, meta, shared_preferences

More

Packages that depend on flutter_ads_orchestrator