Monetizing a Flutter app with AdMob remains one of the most practical ways to earn from mobile apps in 2025. This guide walks you through the current, practical steps — from installing the package to showing test ads and preparing for production.
I'll keep things clear and actionable: copy-paste-ready code examples, common pitfalls, and pro tips you can use right away. Whether you're shipping your first banner or adding rewarded ads, this tutorial covers the full workflow. :contentReference[oaicite:0]{index=0}
Overview
Google's official Flutter plugin for AdMob is the google_mobile_ads package. It supports banner, interstitial, rewarded, native, and app-open ads. The high-level steps are:
- Install the package and update native files.
- Initialize the Mobile Ads SDK at app startup.
- Load and show ads using the provided ad classes.
- Test with test ad unit IDs; replace with real IDs when publishing.
The official quick start and examples are the best reference while you work. :contentReference[oaicite:1]{index=1}
Causes / Reasons You Might See Issues
- Not initializing the SDK before requesting ads — leads to failed requests.
- Using production ad unit IDs during development — risk of invalid activity and account flags.
- Missing or incorrect Android/iOS native configuration (manifest, plist, or Gradle settings).
- Outdated google_mobile_ads package or incompatible Flutter SDK version.
Most integration problems are configuration-related — check initialization, platform files, and package compatibility first. :contentReference[oaicite:2]{index=2}
Step-by-step Guide
1. Add the package
Edit pubspec.yaml and add the package. Use a recent version compatible with your Flutter SDK — in 2025 this package is actively maintained, so prefer the latest stable release.
dependencies:
flutter:
sdk: flutter
google_mobile_ads: ^6.0.0
// then run:
// flutter pub get Confirm the version on pub.dev before locking to a specific constraint. :contentReference[oaicite:3]{index=3}
2. Native platform setup (quick checklist)
Android
- Open
android/app/src/main/AndroidManifest.xmland add thecom.google.android.gms.ads.APPLICATION_IDmeta-data (use the sample/test id while developing). - Make sure Gradle uses a recent Android Gradle Plugin and Google Maven repo.
iOS
- Open
ios/Runner/Info.plistand add your AdMob App ID asGADApplicationIdentifier(Apple requires this key for AdMob). - Ensure iOS deployment target matches the package requirements.
Refer to the official quick-start for exact XML/Plist snippets. :contentReference[oaicite:4]{index=4}
3. Initialize the SDK in Dart
Initialize as early as possible — usually in main(). The initializer returns a Future, but you only need to wait if your first ad request must happen immediately.
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await MobileAds.instance.initialize();
runApp(const MyApp());
} 4. Example — Simple Banner Ad
This example shows how to load and display a banner with the package's BannerAd class. Use test ad unit IDs while developing.
class BannerAdWidget extends StatefulWidget {
@override
_BannerAdWidgetState createState() => _BannerAdWidgetState();
}
class _BannerAdWidgetState extends State<BannerAdWidget> {
late BannerAd _bannerAd;
bool _isLoaded = false;
@override
void initState() {
super.initState();
_bannerAd = BannerAd(
adUnitId: BannerAd.testAdUnitId,
size: AdSize.banner,
request: AdRequest(),
listener: BannerAdListener(
onAdLoaded: (ad) { setState(() => _isLoaded = true); },
onAdFailedToLoad: (ad, err) { ad.dispose(); },
),
);
_bannerAd.load();
}
@override
void dispose() {
_bannerAd.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return _isLoaded ? Container(
height: _bannerAd.size.height.toDouble(),
child: AdWidget(ad: _bannerAd),
) : SizedBox.shrink();
}
} 5. Example — Interstitial (load before show)
InterstitialAd.load(
adUnitId: InterstitialAd.testAdUnitId,
request: AdRequest(),
adLoadCallback: InterstitialAdLoadCallback(
onAdLoaded: (InterstitialAd ad) {
ad.show();
ad.dispose();
},
onAdFailedToLoad: (LoadAdError error) { /* handle error */ },
),
); Best Practices
- Always use test ad unit IDs during development to avoid policy violations. :contentReference[oaicite:5]{index=5}
- Dispose of ads (and listeners) to avoid memory leaks.
- Respect user privacy and obtain consent where required (GDPR/CCPA). Configure ad request parameters accordingly.
- Don't place ads where they can be accidentally clicked — follow AdMob placement policies.
- Keep the plugin version up-to-date — the SDK is updated frequently and older versions may be sunsetted. :contentReference[oaicite:6]{index=6}
- Use App Open ads sparingly — they can annoy users if overused.
- Measure: A/B test ad placement and formats in a staged rollout to maximize revenue without hurting UX.
- If you need a unified helper API, wrap ad creation/disposal logic in a small service class for reuse.
Examples (quick checklist)
- Banner in a bottom AppBar — good for consistent revenue with minimal disruption.
- Rewarded video after a natural break (e.g., level complete) — high engagement and good eCPMs.
- Interstitial between content transitions — load beforehand to avoid delays.
FAQ
Q: Which package should I use for AdMob in 2025?
A: Use the official google_mobile_ads package — it's maintained by Google and supports all main ad formats. Check pub.dev for the latest version. :contentReference[oaicite:7]{index=7}
Q: How do I test ads safely?
A: Use test ad unit IDs (the package provides constants like BannerAd.testAdUnitId). Never click your own production ads. :contentReference[oaicite:8]{index=8}
Q: Do I need to initialize SDK on both Android and iOS?
A: You must initialize the SDK in Dart (in main()). Also add the native App ID entries to AndroidManifest and Info.plist as required by AdMob. :contentReference[oaicite:9]{index=9}
Q: What breaks after updating Flutter or the plugin?
A: Breaking changes can come from Gradle, iOS deployment target, or the plugin API. Always read the plugin changelog and the package example before upgrading. :contentReference[oaicite:10]{index=10}
Q: Any tips for production rollout?
A: Gradually replace test IDs with real ad unit IDs, monitor AdMob console for policy warnings, and use analytics to ensure ads don’t harm retention.
Conclusion
Adding AdMob to a Flutter app is straightforward but requires careful platform setup and testing. Initialize early, use test ads during development, handle disposal properly, and stay updated with the plugin releases.
If you want, I can provide a small reusable Dart helper class that wraps banner + interstitial lifecycle, ready to paste into your project. Tell me which ad formats you plan to use and I’ll generate it.