vie_app_ads_manager 1.0.0
vie_app_ads_manager: ^1.0.0 copied to clipboard
Simple ads manager for admob and applovin ads
vie_app_ads_manager #
A lightweight, opinionated ads manager for Flutter that unifies AdMob (Google Mobile Ads) and AppLovin MAX into a single, simple API.
Features #
- Full Ad Format Support: Interstitial, Rewarded, Rewarded-Interstitial (AdMob), App Open, Banner, Native
- Smart Fallback System: Automatic fallback from AdMob to AppLovin MAX when configured
- Remote Config Driven Providers: Select AdMob/MAX and enable flags via Firebase Remote Config
- Widget-Based Ads: Banner and Native ad widgets that auto-select provider via RC
- Event Streaming: Real-time ad lifecycle events for UI state management
- Test Mode Support: Built-in AppLovin MAX mediation debugger and AdMob test ads
- Robust Error Handling: Comprehensive logging and state management
Works with: google_mobile_ads, applovin_max.
Installation #
Add to your pubspec.yaml:
dependencies:
vie_app_ads_manager: ^1.0.0
Then run:
flutter pub get
Platform setup #
Follow the official setup for each SDK your app will use.
-
Google Mobile Ads (AdMob)
- Android: add your AdMob App ID in AndroidManifest.xml
- iOS: add GADApplicationIdentifier to Info.plist
- See: https://pub.dev/packages/google_mobile_ads
-
AppLovin MAX
- No manifest keys required; initialize with the SDK key at runtime
- See: https://pub.dev/packages/applovin_max
Make sure you use your own ad unit IDs in production. Use test IDs during development.
Getting started #
Import the package:
import 'package:vie_app_ads_manager/ads_manager.dart';
Initialize as early as possible (e.g., in main or first page load). You must initialize Firebase and the provided AnalyticsManager to fetch Remote Config before initializing AdsManager:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(home: const Home());
}
}
class Home extends StatefulWidget {
const Home({super.key});
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool _initializing = true;
@override
void initState() {
super.initState();
_initAds();
}
Future<void> _initAds() async {
// 1) Initialize Analytics + Remote Config
await AnalyticsManager.instance.init(
options: /* Your DefaultFirebaseOptions.currentPlatform */,
minimumFetchInterval: Duration.zero,
);
// 2) Provide your AdMob and (optionally) AppLovin MAX IDs
final admobIds = AdmobIds(
appIdAndroid: 'YOUR_ADMOB_APP_ID_ANDROID',
appIdIos: 'YOUR_ADMOB_APP_ID_IOS',
bannerId: 'YOUR_ADMOB_BANNER_ID',
interstitialId: 'YOUR_ADMOB_INTERSTITIAL_ID',
rewardedId: 'YOUR_ADMOB_REWARDED_ID',
rewardedInterstitialId: 'YOUR_ADMOB_REWARDED_INTERSTITIAL_ID',
nativeId: 'YOUR_ADMOB_NATIVE_ID',
appOpenId: 'YOUR_ADMOB_APPOPEN_ID',
);
// Optional: provide AppLovin MAX IDs to enable fallback or to force MAX
final maxIds = MaxIds(
sdkKey: 'YOUR_MAX_SDK_KEY',
bannerId: 'YOUR_MAX_BANNER_ID',
interstitialId: 'YOUR_MAX_INTERSTITIAL_ID',
rewardedId: 'YOUR_MAX_REWARDED_ID',
nativeId: 'YOUR_MAX_NATIVE_ID',
appOpenId: 'YOUR_MAX_APPOPEN_ID',
);
// 3) Initialize AdsManager (it will read provider flags from Remote Config)
await AdsManager.instance.initialize(
admobIds: admobIds,
maxIds: maxIds,
adjustAppToken: 'YOUR_ADJUST_APP_TOKEN',
);
if (!mounted) return;
setState(() => _initializing = false);
}
}
## Remote Config Provider Control
Provider selection and feature flags are controlled via Firebase Remote Config (RC). Configure these keys in RC:
- `show_banner` (bool): enable/disable banner widget
- `native_ad_enabled` (bool): enable/disable native widget
- `show_app_open` (bool): enable/disable app open button/flow
- `banner_provider` (int): 0=off, 1=AdMob only, 2=MAX only
- `interstitial_provider` (int): 0=off, 1=AdMob only, 2=MAX only
- `reward_provider` (int): 0=off, 1=AdMob only, 2=MAX only
- `app_open_provider` (int): 0=off, 1=AdMob only, 2=MAX only
- `native_ad_provider` (int): 0=off, 1=AdMob only, 2=MAX only
AdsManager reads these values during `initialize()` via `AnalyticsManager`.
### How selection works
- `0` → No-Op: show methods return false; widgets render nothing
- `1` → AdMob only (no MAX fallback)
- `2` → MAX only
- Otherwise: default logic attempts AdMob first, with MAX as fallback when available
### Interstitial
```dart
// Provider is selected via RC
final shown = await AdsManager.instance.showInterstitial();
Rewarded #
final shown = await AdsManager.instance.showRewarded(
onEarnedReward: (amount) {
// grant reward
},
);
App Open #
final shown = await AdsManager.instance.showAppOpen();
Widgets #
Banner #
A banner widget that auto-selects provider via Remote Config, with automatic fallback when allowed.
// Default behavior (provider sourced from RC)
const BannerAdManager()
// Custom size
const BannerAdManager(adSize: AdSize.largeBanner)
Note: AdSize is re-exported by this package. You only need:
import 'package:ads_manager/ads_manager.dart';
No direct import from google_mobile_ads is required just to use AdSize.
Native #
A native ad widget that auto-selects provider via Remote Config, with automatic fallback when allowed.
// Default behavior (provider sourced from RC)
const NativeAdManager(height: 300)
// Custom styling
NativeAdManager(
height: 300,
style: NativeTemplateStyle(templateType: TemplateType.medium),
)
Events #
Listen to the stream for ad lifecycle events to drive UI state (e.g., loading spinners):
final sub = AdsManager.instance.onEvent.listen((event) {
final type = event.keys.first; // AdUnitType
final ev = event.values.first; // AdEventType
// handle
});
AdUnitType: banner, interstitial, rewarded, rewardedInterstitial, native, appOpen
AdEventType: loading, loaded, failedToLoad, showed, dismissed, failedToShow, earnedReward
Testing & Debugging #
AppLovin MAX Test Mode #
The ads manager automatically enables AppLovin MAX mediation debugger during initialization for testing purposes. This provides:
- Real-time mediation waterfall information
- Network adapter status
- Test ad controls
- Revenue and performance metrics
AdMob Test Ads Helper #
You can switch to AdMob test IDs at runtime and preload again:
await AdsManager.instance.showTestAds();
This is handy to validate your integration without touching your production IDs.
Provider-Based Testing #
Use the helper to switch to AdMob test IDs. To simulate networks, change RC provider keys at runtime and call AnalyticsManager().refreshRemoteConfig() before showing again.
// Switch to AdMob test IDs and preload test ads
await AdsManager.instance.showTestAds();
// Change RC: banner_provider / interstitial_provider / reward_provider / app_open_provider
await AnalyticsManager().refreshRemoteConfig();
Example #
See the example/ app for a full usage demo with buttons for interstitial, rewarded, app open, banner, and native ads plus event-handling.
Notes & Tips #
General #
- Always use Google's test IDs or your own test placements during development to avoid policy violations.
- AppLovin MAX requires your real SDK key and ad unit IDs. Ensure network permissions and platform setup are complete.
- If you prefer not to use MAX, initialize without
max:and the manager will work with AdMob only.
Provider Behavior #
- Provider 0 (no ads): All show methods return
false. Banner/Native widgets render nothing and do not load. - Provider 1 (AdMob only): No fallback to MAX, even if MAX is configured. Use this for pure AdMob testing.
- Provider 2 (MAX only): Direct MAX ad loading, bypasses AdMob entirely.
- Default (null provider): Smart fallback system - tries AdMob first, falls back to MAX on failure.
- Widgets: Banner and Native widgets respect provider settings and handle fallbacks accordingly.
Performance #
- MAX mediation debugger adds overhead - disable in production builds if needed.
- Provider selection allows you to test individual networks without interference.
- Event streaming helps optimize UI responsiveness during ad loading.
License #
MIT