google_admob_sdk 1.0.3
google_admob_sdk: ^1.0.3 copied to clipboard
A self-managed, high-speed Flutter plugin for Google Mobile Ads Next-Gen SDK & 3rd-Party Ad Networks (AppLovin, Meta, Mintegral, Unity Ads, Pangle, IronSource, Liftoff) with centralized Ad Unit ID man [...]
1.0.3 #
-
Revenue & Analytics Fixes:
- Waterfall Preserved After Every Show: Auto-reload after a fullscreen show now repeats the original
loadAd(originalcustomAdUnitId,AdRequest,screenName,adUnitName, A/B test params) instead of pinning the unit that just served, so the next load starts again from the high-floor unit. The resolved network of the shown ad is no longer reused as a stickyadNetworkoverride. - Splash &
ParallelAdPoolManagerAnalytics: Pool loads logad_request+ health monitor stats; pool shows log revenue (onPaidEvent),iaa_fail_show, clicks andad_complete. EachSharedAdUnitSlothas its ownAdRetryPolicy, reset when connectivity returns. - Firebase Reserved Names:
FirebaseAdLoggerno longer sends the reservedad_clickevent (click data goes toiaa_click) and skips reserved event names andfirebase_/google_/ga_user properties instead of throwing. - iOS Consent Status Mapping:
getConsentStatusmaps UMP values explicitly to the DartConsentStatusorder (iOS ordersrequiredbeforenotRequired); builds without UMP returnunknowninstead ofobtained. - Failed Shows: The frequency-capping cooldown starts only in
onAdShowedFullScreenContent. A failed or throwingshow()disposes the ad, resets the showing flags, logsiaa_fail_showand reloads;PlatformExceptionon show is reported throughonAdFailedToShowFullScreenContent. - Enforced Backoff (
AdRetryPolicy.loadBlockedError): After a failed waterfall,loadAdis refused for the backoff window (2s, 4s, 8s... up to 60s; 3-minute circuit breaker after 5 failures) and offline loads are refused too, all reported throughonAdFailedToLoadinstead of silently returningfalse.
- Waterfall Preserved After Every Show: Auto-reload after a fullscreen show now repeats the original
-
Policy & Compliance:
- COPPA & Meta ATT Propagation (Android & iOS):
MediationConfig.isChildDirectedis forwarded to Meta (setMixedAudience), Vungle (setCOPPAStatus), Mintegral, Unity (setNonBehavioral) and IronSource/LevelPlay (is_child_directed), and mirrored into AdMobtagForChildDirectedTreatmentunless theRequestConfigurationsets it.metaAdvertiserTrackingEnabledreachesFBAdSettingson iOS.setThirdPartyPrivacyConsentreplies only after the flags are applied. - Native Privacy Fixes: iOS now applies privacy flags at init (Dart sends
mediationConfig, Swift readmediationPrivacy). Each 3rd-party setter runs independently, so missing APIs (Pangle 8.xsetGDPRConsent) no longer abort a network's remaining flags. IronSource usesLevelPlay(mediation SDK 9.x); Unity usesUnityAds.setUserConsent/setUserOptOut/setNonBehavioral(4.20+), withMetaDataas fallback. - Consent Gate (
GoogleAdmobSdk.instance.canRequestAds):requestConsentIfRequiredstores the UMP result; while it isfalseevery load fails withLoadAdError.consentRequiredwithout a network request or a counted retry failure. The consent-info request times out afterinfoUpdateTimeout(10s) so the splash never hangs offline;showPrivacyOptionsFormrefreshes the gate. - Click-Safe Layouts: The
NativeAdWidgetclose button moved to a 32px strip outside the ad view (never over assets, CTA or AdChoices;closeButtonAlignmentdefaults totopRight). Fullscreen variants 2, 8 and 10 now close through the templateClosebutton and keep a top close icon. ThetallMediaProgressCloseprogress bar follows the real countdown instead of a fixed 45%. - No Impressions Under the Shimmer:
eagerSurfaceMountnow defaults tofalseforNativeAdWidgetandBannerAdWidget; when enabled,minShimmerDurationis ignored. - Release Logging & PII:
ConsoleAdLogger.useDeviceLogdefaults to!kReleaseMode;initialize(enableLogging:, enableDeviceLog:)default to off in release (anonLogcallback still receives logs).AnalyticsUserProperties.userName/userEmailare deprecated and skipped byFirebaseAdLogger, which also redacts e-mail addresses (and phone numbers in search/feedback text). - No Silent Test Ads in Release (
AdIdConfig.allowTestAdUnitIds): Defaults to!kReleaseMode. In release builds a missing or Google test ad unit ID resolves to''and the load fails withLoadAdError.missingAdUnitIdplus a one-time warning.AdIdConfig.test()keeps test IDs allowed.
- COPPA & Meta ATT Propagation (Android & iOS):
-
Lifecycle & Leak Fixes:
- Reused Ads:
NativeAdWidget/BannerAdWidgetrestore the ad's previous listener when they let go of it and ignore callbacks for ads they no longer show, so disposed widgets stop receivingonPaidEvent/onAdClicked(no duplicated revenue). - Superseded Banner Requests: A banner request replaced by a hedged fallback or pool rescue can no longer touch timers, start a fallback or replace the ad on screen.
- Pools:
NativeAdPool.set/BannerAdPool.setrelease the ad they replace;NativeAdPoolforgets key mappings when ads leave the keyed pool;BannerAdPool.clear(),disposeAd()andreleaseOrRescueKeyedAd()complete pending waiters (no widget stuck on shimmer). Widgets dispose ads they loaded themselves even when apreloadedAdwas given (the caller still ownspreloadedAd). - Disposed Ads:
load()afterdispose()no longer reaches native, andshow()on a disposed ad reportsonAdFailedToShowFullScreenContent. - Countdown Dialog:
showAdSafelyandNativeAdInterstitialDialogclose only their own route (dismissOwnRoute) instead of popping the user's screen. - Fullscreen Watchdog (
AdInstanceManager): A show that never reports back fails afterfullScreenShowTimeout(10s); a lost dismiss is reported afterfullScreenMaxOnScreen(5 min), orfullScreenResumeGrace(3s) after the app resumes on Android. Late native events are dropped, soisAnyFullScreenAdShowingand the splash race always recover. - Shared Interstitial Cooldown (
GoogleAdmobSdk.instance.lastInterstitialShowTime): EveryInterstitialAdManager(includingforUnitKey) andParallelAdPoolManagercheck the same cooldown;resetCooldown()clears it. - Banner Resizing: Adaptive banners are re-requested after rotation / split-screen resize (300ms debounce) and when
adUnitId, size or collapsible placement change (didUpdateWidget). - Debug Crash:
NativeAdWidget(borderRadius:)withoutdecorationno longer asserts. - Slow-Network Detection:
isSlowNetworkneedsslowLoadsBeforeFastTrack(2) consecutive slow loads or a network error withinslowNetworkWindow(60s); any fast response ends it, so high-floor units are no longer skipped after a single slow load.
- Reused Ads:
-
Architecture & Maintenance:
FullScreenAdManager<T>:InterstitialAdManager,RewardedAdManager,RewardedInterstitialAdManagerandAppOpenAdManagernow share one implementation (rewarded formats via theRewardedFullScreenAdmixin); public APIs are unchanged. Fixes the waterfall skipping its first fallback on slow networks.isAdAvailable/isAdLoadedare side-effect free.- Global Ads Switch (
GoogleAdmobSdk.instance.adsEnabled/adsEnabledListenable): For premium users or a Remote Config kill switch. Whilefalse, loads fail withLoadAdError.adsDisabled, fullscreen ads and splash races are skipped, and ad widgets render nothing; mounted widgets load again when re-enabled. - Deprecations:
setUserControlledAppMuted(usesetAppMuted),setApplicationVolume(usesetAppVolume) andGoogleAdmobSdk.instance.health(usehealthMonitor). - File Layout:
NativeAdPool,BannerAdPool,FigmaNativeAdPreviewand the Firebase / Console / Composite loggers moved topartfiles;AdCountdownConfig/AdCountdownDialogmoved toad_countdown_dialog.dart(still exported). MediationConfig.copyWith:setPrivacyConsentno longer dropsenableHedgedParallelFallback. Unused fields (enableTestMode,credentials,networkExtras,preloadBiddingSignals) are documented as reserved.- Docs:
AGENTS.mdandREADME.mdcorrected (consent-first quickstart, enforced backoff, 55-minute TTL, slow-network rules,eagerSurfaceMount, ads switch). - Tests: Added
p0_fixes_test.dart,p0_policy_test.dart,p1_lifecycle_test.dartandp2_architecture_test.dart(147 tests in total).
-
Build Fixes:
- Added the 9 drawables used by
admob_native_cctv_horizontal.xml,admob_native_cctv_medium.xmlandadmob_native_full.xml(admob_rounded_card_cctv,ic_ad_info, ...), fixing:google_admob_sdk:verifyReleaseResourcesin release builds.
- Added the 9 drawables used by
-
Migration Notes:
- Call
GoogleAdmobSdk.requestConsentIfRequired()beforeGoogleAdmobSdk.initialize(). - Release builds need real ad unit IDs for every format they use (or
AdIdConfig.test()/allowTestAdUnitIds: truefor internal builds). - Pass
enableLogging: trueto keep console logs in release. showCloseButton/closeNativeShowBanneradd a 32px strip to the native widget height.- Adaptive banners make an extra request on each rotation.
- Call
1.0.2 #
- Banner Creative Snug-Fitting & Letterbox Elimination (
BannerAdWidget/BannerAdWidget.adaptive):- AdMob WebView Background Normalization:
- Automatically clears AdMob WebView's
<body style="background-color:#000000">black letterbox background totransparent, preventing black bars when adaptive slots are taller than the creative. - Re-aligns internal
#google-center-divtovertical-align: topso banner creatives flush snugly against the top edge and align with the"Test Ad"badge.
- Automatically clears AdMob WebView's
- Rendered Creative Height Auto-Detection (
syncBannerWebViewCreativeBounds):- Injected lightweight JavaScript evaluator into
s41(gmaWebView) to probe#google_image_div/ rendered image bounds and fireonAdSizeChangedto shrinkBannerAdWidgetto the exact rendered creative height (e.g.53dpfor scaled468x60ads in a411x64adaptive slot).
- Injected lightweight JavaScript evaluator into
- Platform View Container Protection (
AdPlatformContainerFrameLayout):- Created custom
AdPlatformContainerFrameLayoutcontainer on Android that measuresAdViewwithMeasureSpec.UNSPECIFIEDwhile clipping to the exact rendered creative height, completely preventing GMA Next-Gen SDK's"Not enough space to show ad"error.
- Created custom
- AdMob WebView Background Normalization:
- Workspace & Package Cleanup:
- Removed internal tracking spreadsheet from repository and package distribution.
- Synchronized all developer rules and workflow skills in
.agents/rulesand.agents/skillswith v1.0.2 architecture and standards.
1.0.1 #
- Dynamic / Intrinsic Height Auto-Resizing (
height == null) without Ad Reloading:- Native Ad Intrinsic Height Auto-Adjustment (
NativeAdWidget):- Changed
heightto default tonullacrossNativeAdWidgetand all named preset constructors (.small,.medium,.fromPreset,.normal,.nativeViewSmall,.medium01,.nativeView,.figmaMedium,.mediaView,.mediaViewTopCta,.mediaViewSplitCenter,.mediaViewSplitRight,.mediaViewLarge,.big,.cls,.interstitial,.dark). - When
height == null, the widget automatically resizes to the exact measured intrinsic height of the native ad (platformAdHeight/loadedHeight) without triggering an ad reload. - When an explicit
heightis provided (height != null), the widget strictly respects the caller's specified height. - Added
onAdSizeChangedlistener callback toAdWithViewListenerandNativeAdListener. - Synchronized layout rebinding (
rebindLayout) andswapPlatformViewAdto notify Flutter of newly measured dimensions and updateSizedBoxdimensions in-place.
- Changed
- Banner Ad Dynamic Height Auto-Adjustment (
BannerAdWidget):- Added optional
widthandheightparameters (nullby default) toBannerAdWidgetandBannerAdWidget.adaptive. - When
height == null, the container dynamically resizes to the loadedplatformAdSizewithout reloading the ad. - Updated
BannerAdWidget.adaptiveandBannerAdPoolto request standard'anchoredAdaptive'(AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize) instead of'largeAnchoredAdaptive', matching Google's official adaptive height formula (~50dp–64dpon phones) and preventing oversized~128dpslots with black bars above and below60dpcreatives. - Added
measureBannerAdViewIntrinsic,resolveBannerLoadedSizeDp,syncBannerWebViewCreativeBounds, andAdPlatformContainerFrameLayoutinGoogleAdmobSdkPlugin.ktto queryBannerAd.getAdSize(), clear AdMob WebView's<body style="background-color:#000000">letterbox background, align#google-center-divtovertical-align: top, and resizeBannerAdWidgetto the exact rendered#google_image_divcreative height (53dpfor scaled468x60inside411x64) without triggering"Not enough space to show ad". - Added
onAdSizeChangedcallback toBannerAdListenerand wired size change notifications on initial load, adaptive re-measurements, and auto-refreshes (onAdRefreshed).
- Added optional
- Elimination of Excess Blank Space & Layout Measurement Hardening:
- Android (
GoogleAdmobSdkPlugin.kt):- Added
measureNativeAdViewIntrinsicto compute the true intrinsic content height viaMeasureSpec.UNSPECIFIED(temporarily constraining internal SDK AdChoices overlay views toWRAP_CONTENTduring measurement). - Added
createContainerLayoutParamsForAdViewusingWRAP_CONTENTheight for inlineNativeAdViewandAdView(instead ofMATCH_PARENT), completely eliminating unwanted blank white space beneath native ad cards. - Fixed pre-mounted container squashing for
BannerAd: banners (~90dp) now measure withMeasureSpec.UNSPECIFIEDheight instead of being clipped to the initial shimmer container height (~69dp). - Attached
containerLayoutListeners(OnLayoutChangeListener) to dynamically reportonAdSizeChangedevents to Flutter whenever container dimensions change.
- Added
- iOS (
GoogleAdmobSdkPlugin.swift):- Added intrinsic height calculation for Figma presets, returning
loadedWidthandloadedHeightinnativeMetadataandonAdLoaded. - Added native handler for
rebindNativeAdLayoutand updatedswapPlatformViewAdto emitonAdSizeChanged.
- Added intrinsic height calculation for Figma presets, returning
- Android (
- Build & Gradle Duplicate Class Fixes:
- Resolved
:app:checkDebugDuplicateClassesbuild failure caused by duplicatecom.google.android.gms.ads.*classes between Next-Gen SDKads-mobile-sdk:1.6.0and transitiveplay-services-ads-api:25.5.0via explicit Gradle exclude rules inandroid/build.gradle.ktsandexample/android/app/build.gradle.kts.
- Resolved
- Native Ad Intrinsic Height Auto-Adjustment (
1.0.0 #
- Google Mobile Ads (GMA) Next-Gen SDK (
com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:1.6.0) Migration & Compliance Hardening:- GMA Next-Gen SDK Native Engine:
- Migrated Android native runtime from legacy
com.google.android.gms:play-services-adstocom.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:1.6.0andcom.google.android.ump:user-messaging-platform:4.0.0. - Added
InitializationConfig, format-specificAdRequestclasses (BannerAdRequest,NativeAdRequest,AppOpenAdRequest),BannerAd.isCollapsible(),MobileAds.setUserControlledAppMuted(...), and Next-Gen Preloader APIs (InterstitialAdPreloader,RewardedAdPreloader,RewardedInterstitialAdPreloader,AppOpenAdPreloader). - Upgraded all 7 bundled mediation adapters to their latest Next-Gen compatible artifacts (
applovin:13.6.4.2,facebook:6.22.0.1,mintegral:17.1.81.1,unity:4.21.0.0,pangle:8.3.0.4.0,ironsource:9.6.1.0,vungle:7.7.8.1) with scoped exclusion of legacyplay-services-ads. - Updated all built-in XML Native layouts (
admob_native_cls.xml,admob_native_mediaview.xml,admob_native_mediaview_bottom_cta.xml,admob_native_interstitial.xml,admob_native_small.xml) tocom.google.android.libraries.ads.mobile.sdk.nativead.NativeAdView,MediaView, andAdChoicesView.
- Migrated Android native runtime from legacy
- UMP "Privacy Options" (GDPR) Compliance (Android & iOS):
- Added
ConsentInformation.instance.getPrivacyOptionsRequirementStatus(),ConsentInformation.instance.isPrivacyOptionsRequired(),ConsentForm.showPrivacyOptionsForm(...), andGoogleAdmobSdk.showPrivacyOptionsForm(). - Implemented
getPrivacyOptionsRequirementStatusandshowPrivacyOptionsFormon both Android (UserMessagingPlatform.showPrivacyOptionsForm) and iOS (ConsentForm.presentPrivacyOptionsForm).
- Added
- Consent-Safe Boot Warm-Up & Strict
InitializationConfigHandling:- Removed premature
MobileAds.initializefromAdmobFastBootProviderso process boot only warms up Chromium WebView, DNS cache, and XMLViewPools without starting the AdMob SDK or 3rd-party mediation adapters before UMP consent. - Added release-build validation in
resolveAdMobAppIdto fail fast with a clearMISSING_APP_IDerror ifcom.google.android.gms.ads.APPLICATION_IDis omitted in release builds. - Added Meta Audience Network CCPA Limited Data Use (
AdSettings.setDataProcessingOptions(["LDU"], 0, 0)) and structured warning logs inapplyThirdPartyPrivacyConsent.
- Removed premature
- Next-Gen Adaptive Banner
AdSizeAPIs:- Tagged adaptive
AdSizeinstances withsizeType('anchoredAdaptive','largeAnchoredAdaptive','inlineAdaptive','fluid'),orientation, andmaxHeight. - Resolved native
AdSizeon Android and iOS usingAdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize,AdSize.getLargeAnchoredAdaptiveBannerAdSize, andAdSize.getInlineAdaptiveBannerAdSize, returning resolved dimensions viaBannerAd.platformAdSize.
- Tagged adaptive
- Zero-Leak In-Flight Ad Disposal & Main-Thread UI Safety:
- Tracked
disposedAdIdsanddisposeGenerationin native Android & iOS so in-flight ads that finish loading afterdisposeAd(adId)are immediately destroyed (ad.destroy()) and never leaked in memory. - Enforced
runOnMainThreadacross all View/MethodChannel callbacks invoked from GMA Next-Gen SDK's backgroundPublisher Callbackthreads.
- Tracked
- GMA Next-Gen SDK Native Engine:
0.1.0 #
- Complete Figma Native (23 Presets) & Native Fullscreen + Video (12 Variants) Catalog +
0.0msFrame #1 Rendering Engine:- 23 Built-in Figma
NativeTemplatePresetLayouts:- Added full support and named constructors on
NativeAdWidgetandAdmobNativeStylesfor all Figma Native designs:small(100dp),normal(132dp,57:964),nativeViewSmall(136dp,57:1032),medium01(182dp,57:977),nativeView(203dp,57:1013),medium/figmaMedium(272dp,57:992),mediaView(272dp,57:1049),mediaViewTopCta(272dp,57:1069),mediaViewSplitCenter(272dp,57:1089),mediaViewSplitRight(272dp,57:1109),mediaViewLarge(272dp,57:1129),big(282dp,57:1149),cls(282dp,57:1167),clsOrange(282dp,57:1185),interstitial(380dp,70:6181),dark(272dp), plus 7 fullscreen layout presets.
- Added full support and named constructors on
- 12 Built-in Figma
NativeFullScreenVariant(Fullscreen & Video) Layouts:- Added
NativeFullScreenVariant(classicCard,tallMediaStackedButtons,headerTopTallMedia,tallMediaArrowNext,immersiveVideo,segmentedArrowNext,segmentedClose,segmentedSplitButtons,tallMediaProgressClose,blurredCardStackedButtons,segmentedClassicCard,segmentedFloatingCta) matching Figma nodes57:1203–57:1540. - Added embeddable
NativeFullScreenAdWidget(with 12 named constructors) and upgradedshowNativeAdInterstitialDialog+NativeAdInterstitialDialog.warmUp(...).
- Added
0.0msFrame #1 Dual-Layer Instant Render &0msHot-Swap (Android & iOS Parity):- Implemented
FigmaNativeAdPreviewinad_core.dartrendering all 23 Figma presets in0.0mson Frame #1 on both Android and iOS usingNativeAdMetadata(headline,body,callToAction,advertiser,starRating,iconBytes,imageUri,mediaAspectRatio,hasVideoContent). - Upgraded
GoogleAdmobSdkPlugin.kt(Android) andGoogleAdmobSdkPlugin.swift(iOS) with pre-inflated/pre-boundNativeAdView/GADNativeAdViewbuilders, Eager Surface Pre-Mounting (containerId = -widgetId), and0msswapPlatformViewAdhot-swapping. - Added layout-accurate
NativeAdShimmer(NativeShimmerLayout) skeletons for all 23 presets to ensure Zero Cumulative Layout Shift (Zero-CLS).
- Implemented
- 23 Built-in Figma
0.0.9 #
- Advanced Revenue & Enterprise Monetization Optimizations:
- Anchored Adaptive Banners (
BannerAdWidget.adaptive):- Added
BannerAdWidget.adaptive(...)factory andisAdaptive: truesupport to dynamically calculate optimal anchored banner height usingAdSize.getLargeAnchoredAdaptiveBannerAdSize(...). - Eliminates letterboxing, side gutters, and vertical text clipping across modern devices and tablets.
- Added
- High-eCPM Collapsible Banner Ads:
- Added
CollapsiblePlacementenum (none,bottom,top) and parameter toBannerAdWidget. - Automatically injects
{'collapsible': 'bottom'|'top'}extras intoAdRequest, rendering an expandable overlay on first load with a close toggle that yields 2x–4x higher eCPM compared to static banners.
- Added
- Server-Side Verification (SSV) for Rewarded Ads:
- Added
ServerSideVerificationOptionssupport toRewardedAdManagerandRewardedInterstitialAdManager. - Exposes
setServerSideVerificationOptions(...)andserverSideVerificationOptionsparameter inloadAd(...). - Google AdMob servers validate rewarded ad views through direct webhook callbacks to the backend, preventing client-side reward manipulation and virtual currency spoofing.
- Added
- Automated Background-to-Foreground App Open Reactor (
AppLifecycleReactor):- Implemented
AppLifecycleReactorimplementingWidgetsBindingObserverto manage background-to-foreground transitions. - Configurable
minBackgroundDuration(default 15s) prevents annoying ad popups on rapid app switching or system permission dialogs. - Configurable
minShowInterval(default 5 minutes) and customcanShowAdpredicate (e.g. skip ads during checkout flows).
- Implemented
- COPPA & Ad Content Rating Compliance in Initialization:
- Added
maxAdContentRating(MaxAdContentRating.g,pg,t,ma) andageRestrictedTreatment(TagForChildDirectedTreatment.yes,no) inGoogleAdmobSdk.initialize. - Ensures compliance with Google Play Families Policy and EU GDPR-K.
- Added
- Google UMP (User Messaging Platform) Consent Flow & Enterprise Tools:
- Added
GoogleAdmobSdk.requestConsentIfRequired(...)to automate IAB TCF v2.2 GDPR/UK consent management, preventing 100% No-Fill (Error Code 3) penalties in European markets. - Added
GoogleAdmobSdk.openAdInspector(...)for real-time on-device mediation and bidding inspection. - Added
GoogleAdmobSdk.setAppMuted(bool)andGoogleAdmobSdk.setAppVolume(double)for global video ad audio control.
- Added
- Fullscreen Concurrency Guards & Ad Collision Prevention:
- Added atomic
isShowingstate tracking across all fullscreen managers (InterstitialAdManager,RewardedAdManager,RewardedInterstitialAdManager,AppOpenAdManager). - Added global
GoogleAdmobSdk.instance.isAnyFullScreenAdShowingandlastFullScreenAdDismissedTimestate coordination. - Safely blocks rapid double-tap or simultaneous
showAd/showAdSafelyrequests, eliminating nativePlatformException: Ad already presentedexceptions. - Protects
AppLifecycleReactorby automatically suppressing App Open Ads immediately after closing Interstitial or Rewarded Ads.
- Added atomic
- In-Flight Request Deduplication & Multi-Caller Caching (
Completer<bool>):- Implemented single-flight request deduplication across all 4 fullscreen managers (
InterstitialAdManager,RewardedAdManager,RewardedInterstitialAdManager,AppOpenAdManager). - Concurrent
loadAd()calls attach to the single active network request instead of triggering multiple duplicate requests or dropping calls withfalse. - Eliminates request spamming to Google AdMob servers and preserves high Match Rate (> 85-95%).
- Implemented single-flight request deduplication across all 4 fullscreen managers (
BannerAdPool& Multi-Widget Banner Caching:- Added
BannerAdPoolandcacheKey/preloadedAdproperties toBannerAdWidgetandBannerAdWidget.adaptive, matchingNativeAdPool. - Allows caching and reusing banners across tabs and screen transitions without repeatedly requesting new banner ads.
- Added
- Anchored Adaptive Banners (
0.0.8 #
- Critical AdMob Metrics, Traffic Quality & Match/Show Rate Protection:
- Ad Quality, Show Rate & Match Rate Protection Architecture:
- Ad TTL & 60-Minute Expiration Auto-Invalidation:
- Added
maxAdAge(60 minutes for Interstitial, Rewarded, and Rewarded Interstitial; 4 hours for App Open) in accordance with Google AdMob policy. - Added
isAdAvailableandloadTimegetters across all managers. - Automatically invalidates and disposes expired ads to prevent displaying stale ads that cause invalid impressions and account-level policy penalties.
- Added
- Exponential Backoff & Circuit Breaker (
AdRetryPolicy):- Integrated
AdRetryPolicyinto all managers to prevent rapid request storms onERROR_CODE_NO_FILL(Code 3) or network loss. - Implements backoff sequence (2s $\rightarrow$ 4s $\rightarrow$ 8s $\rightarrow$ 16s $\rightarrow$ 60s) and trips a Circuit Breaker when consecutive failures exceed the threshold, protecting Ad Unit Quality Score and Match Rates.
- Integrated
- Smart Auto-Reload & Delay Capping:
- Added
GoogleAdmobSdk.instance.enableAutoReloadandautoReloadDelayto eliminate orphan preloads (ads loaded upon dismissal that are abandoned when the user leaves the app).
- Added
- Realtime Inventory Health Monitor (
AdHealthMonitor):- Added
AdHealthMonitoraccessible viaGoogleAdmobSdk.instance.healthMonitor(.health). - Computes realtime Match Rate, Show Rate, and CTR with automatic warnings when Show Rate $< 50%$ or consecutive No-Fill errors occur.
- Added
- Ad TTL & 60-Minute Expiration Auto-Invalidation:
- Frequency Capping & Safe Interstitial Flow:
- Added
InterstitialAdManager.sharedsingleton instance to retain preloaded interstitial ads across screens and lifecycle transitions. - Integrated Frequency Capping (
minShowInterval, defaults to 180 seconds - 3 minutes) withcanShowandremainingCooldowngetters to prevent excessive CTR and accidental clicks (Invalid Traffic policy penalties). - Added
showAdSafely(...)with configurable countdown notice dialog (AdCountdownDialog/showWarningCountdown), smoothly notifying users before fullscreen ad presentation. - Added
AdCountdownConfigand exposed parameterscountdownTitle,countdownSubtitle, andcountdownConfigacrossInterstitialAdManager,RewardedAdManager, andRewardedInterstitialAdManagerfor custom styling and internationalization (i18n). - Enhanced
showNativeAdInterstitialDialogwith custom styling parameters (backgroundColor,height,showProgressBar,progressColor,closeButton,topBar,contentPadding). - Standardized all user-facing dialogs, examples, and internal doc comments to English.
- Added
- Rewarded & Rewarded Interstitial Shared Singletons:
- Added
RewardedAdManager.sharedandRewardedInterstitialAdManager.sharedto resolve 0% Show Rate caused by orphan preloaded ads being disposed during screen navigation. - Added
showAdSafely(...)to both rewarded managers.
- Added
- App Open Ad Shared Singleton:
- Added
AppOpenAdManager.sharedglobal instance for app open lifecycle handling.
- Added
- Banner & Native Ad KeepAlive & State Retention:
- Integrated
AutomaticKeepAliveClientMixin(keepAlive: trueby default) in bothBannerAdWidgetandNativeAdWidgetto eliminate ad destruction and reload cycles during ListView/GridView/TabBarView scrolling and tab switches. - Added
NativeAdPoolcache pool (cacheKey) andpreloadedAdsupport to reuse loaded native ads across feeds and tabs, resolving the 24–34 impressions/user spam issue.
- Integrated
- Bidding & Mediation Troubleshooting (0.00% Bids Resolution):
- Added Pangle (TikTok / ByteDance) mediation adapter setup for Android (
com.google.ads.mediation:pangle:6.4.0.6.0) and iOS (GoogleMobileAdsMediationPangle). - Added comprehensive root-cause analysis and troubleshooting checklist in
doc/MEDIATION_SETUP_GUIDE.mdandREADME.mdaddressing why apps experience 0.00% bids when native adapters are omitted.
- Added Pangle (TikTok / ByteDance) mediation adapter setup for Android (
- Ad Quality, Show Rate & Match Rate Protection Architecture:
0.0.7 #
- Native Ad Styles, Presets & Custom Layouts:
- Added
NativeTemplatePresetenum with clean preset names (mediaView,cls,interstitial,small,dark) matching modern design tokens, with deprecatedfigma*aliases for backward compatibility:mediaView: Matches Figma node70:6182(Ads?Native_mediaview) with#1A90FFCTA, white background, 10px corner radius, and subtle typography.cls: Matches Figma node70:6183(Ads/Native_cls) with CLS-optimized layout and palette.interstitial: Matches Figma node70:6181(Ads Interstitial) with prominent 16px title, 14px body, and 10px rounded corners.small: Compact small template using the modern design tokens.dark: Dark mode theme (#1E1E1Ebackground).
- Added
AdmobNativeStylesfactory class with predefined factory methods (mediaView,cls,interstitial,small,dark,fromPreset, andcustom) alongside deprecatedfigma*aliases. - Enhanced
NativeAdWidgetwithtemplatePreset,decoration,margin,padding, andborderRadiusproperties. Gracefully defaults tomediaViewwhen neithernativeTemplateStylenorfactoryIdis supplied, preventing assertion errors out-of-the-box. - Added Custom Layout Support in
NativeAdWidget:layoutBuilder: Custom builder allowing developers to place the ad view anywhere in their custom widget hierarchy.- Integrated layout slots:
header,footer,badge,badgeAlignment,showCloseButton,onClose,closeButtonAlignment, andaspectRatio. - Added
customOptionsmap forwarding toNativeAdfor custom platform factories.
- Added
showNativeAdInterstitialDialogandNativeAdInterstitialDialogreproducing the fullscreen Figma "Ads Interstitial" layout (Node70:6181) with top bar indicator, close button, and Databuckets tracking. - Added complete native platform factory guide doc/CUSTOM_NATIVE_LAYOUTS.md with Android XML and iOS Swift templates.
- Updated Example app with interactive Native Ad styles switcher (MediaView vs CLS) and fullscreen Native Interstitial Dialog demonstration.
- Added
0.0.6 #
- Tag & Logging Enhancements:
- Standardized bracketed tag
[GoogleAdmobSdk]across all log outputs for easy search and filtering in Android Studio Logcat. - Added configurable
logTagparameter (defaults to[GoogleAdmobSdk]) inGoogleAdmobSdk.initialize, with runtime getterGoogleAdmobSdk.instance.logTagand setterGoogleAdmobSdk.instance.setLogTag(String). - Added custom log interceptor callback
onLoginGoogleAdmobSdk.initializeand runtime setterGoogleAdmobSdk.instance.setOnLog(callback). - Silenced repetitive uninitialized Firebase warning in
FirebaseAdLoggerwhen Firebase is not configured in the host app.
- Standardized bracketed tag
- Dependency Compatibility:
- Expanded dependency ranges:
firebase_analytics: '>=12.4.6 <13.0.0'andfirebase_core: '>=4.13.0 <5.0.0'for maximum compatibility across Flutter apps.
- Expanded dependency ranges:
0.0.5 #
- Device & Console Logging Enhancements:
- Added
enableDeviceLogandenableLoggingflags inGoogleAdmobSdk.initializeto output formatted logs directly to Android Studio Logcat and iOS console across all build modes (Debug, Profile, and Release). - Added runtime logging toggle
GoogleAdmobSdk.instance.setLoggingEnabled(bool). - Formatted output displaying detailed diagnostics for AdMob Load Success (format, unit ID, placement, load duration ms, network), Load Failure (error code, error message, duration), Impressions (with revenue value), Clicks, and Fullscreen Ad Completions.
- Added
0.0.4 #
- Android Built-in Kotlin Migration:
- Migrated plugin build configuration from external Kotlin Gradle Plugin (
org.jetbrains.kotlin.android) to AGP Built-in Kotlin (id("com.android.library")), resolving Flutter KGP deprecation warnings. - Configured unified JVM target 17 across Java and Kotlin tasks (
tasks.withType<KotlinCompile>).
- Migrated plugin build configuration from external Kotlin Gradle Plugin (
- Dependency Updates & Compatibility:
- Updated and verified dependencies:
google_mobile_ads: ^9.1.0,firebase_analytics: ^12.4.6,firebase_core: ^4.13.0,flutter_lints: ^6.0.0. - Re-exported
firebase_coreandfirebase_analyticsfrom the main barrel file for convenient access. - Made
FirebaseAdLoggerresilient with lazy initialization to prevent crashes when Firebase is not yet configured.
- Updated and verified dependencies:
- AI-Ready Context & Developer Documentation:
- Added root
AGENTS.md, workspace rules (.agents/rules/), and workflow skill (.agents/skills/google-admob-sdk-guide/). - Added comprehensive architecture, ad format, and Databuckets tracking documentation in
doc/(ARCHITECTURE.md,AD_FORMATS_GUIDE.md,DATABUCKETS_TRACKING.md,TESTING_AND_CONTRIBUTING.md).
- Added root
- Package Publishing & Quality:
- Optimized
.pubignoreand.gitignoreto keep published archive size ultra-compact (~267 KB). - Excluded build artifacts in
analysis_options.yamlwith 0 analysis issues and 100% test coverage. - Synchronized
exampleproject dependencies and configuration.
- Optimized
0.0.3 #
- Fixed
onPaidEventsetter error inBannerAdWidgetandNativeAdWidgetby passingonPaidEventdirectly as a parameter inBannerAdListenerandNativeAdListener. - Expanded
logAdRequestwith support for full Databuckets Sheet 41 parameters:ad_request_id,ad_unit_name,ad_mediation,screen_name,error_code,error_message,ad_mediation_ab_test_name,ad_mediation_ab_test_variant,session_number,ad_source_instance,ad_source_instance_id,ad_source,ad_source_id,media_format. - Added dual event firing for Sheet 41 Universal IAA events (
iaa_request,iaa_loaded,iaa_fail_load,iaa_impression,iaa_fail_show,iaa_click,iaa_complete) alongside legacyad_*events. - Updated all ad widgets (
BannerAdWidget,NativeAdWidget) and ad managers (InterstitialAdManager,RewardedAdManager,RewardedInterstitialAdManager,AppOpenAdManager) to accept the new tracking parameters and automatically log them during ad load requests. - Fully verified and aligned all IAA tracking events with
Technify <> Databuckets - 41.csvspecification.
0.0.2 #
- Added
adKeyparameter support across all ad widgets and managers, sendingad_keyand type-specifickey_<ad_type>parameters (key_banner,key_interstitial,key_rewarded,key_rewardedInterstitial,key_appOpen,key_native) to Firebase Analytics. - Added
RewardedInterstitialAdManagerfor Rewarded Interstitial Ads with official Google test IDs. - Added
NativeAdWidgetfor Native Ads with customizableNativeTemplateStyleandNativeAdOptions. - Added customizable
progressIndicatorproperty toBannerAdWidgetandNativeAdWidget. - Added comprehensive unit test suite covering all configurations, loggers, and ad managers.
0.0.1 #
- Initial release of
google_admob_sdk. - Added
GoogleAdmobSdkmanager for centralized SDK initialization. - Added
AdIdConfigfor managing Android & iOS Ad Unit IDs with Google test IDs fallback. - Added
AdAnalyticsLoggersupportingFirebaseAdLoggerandConsoleAdLogger. - Added
BannerAdWidgetwidget for automatic banner state management. - Added
InterstitialAdManager,RewardedAdManager, andAppOpenAdManager.