feat(android): add opt-in support for GMA Next-Gen SDK - #882
Conversation
Adds an opt-in Android build path against Google's newer GMA Next-Gen SDK (ads-mobile-sdk), selected via a `google_mobile_ads_sdk` app.json flag (or `googleMobileAdsSdk` Expo config-plugin parameter). Defaults to the existing legacy SDK (play-services-ads), so existing apps are unaffected. - Dual native implementations per ad format under android/src/legacy and android/src/nextgen, selected at build time via a Gradle source set switch (init/consent, Interstitial, Rewarded, RewardedInterstitial, AppOpen, Banner, Native Ads). - GMA Next-Gen SDK has no Google Ad Manager equivalent, so Ad Manager ad unit IDs are explicitly rejected under next-gen rather than silently degrading. - Excludes play-services-ads from the classpath when next-gen is selected, since both SDKs ship classes in the same Java package and cannot coexist. - Exposes `mobileAds().googleMobileAdsSdk` so JS can detect which SDK variant is active (e.g. to hide Ad Manager specific UI). - Adds Expo config-plugin support, CI build matrix coverage, and docs (docs/next-gen-sdk.mdx).
|
To preview the documentation for this pull request, visit the following URL: docs.page/invertase/react-native-google-mobile-ads~882
|
|
jet's "Run All" crashes with "Maximum update depth exceeded" on React 19/RN 0.86. Also can't find where jet/mocha actually gets invoked anywhere - no mocha, no config, CI just does react-native run-android. Might be worth moving to Detox at some point? |
|
Hey @exzos28 👋 ! This is amazing, thank you - also, an amazing coincidence - over @invertase we'd noticed this push for Android next gen now and we've got some time planned starting a couple days ago to not only adopt it here but to give the whole repository a refresh (with Android Next Gen being just one piece) We've been busy doing analysis on the same but we hadn't published anything yet. Let me see how you've done the work for the NextGen adoption and see what I can get in for you now quickly or what we can harvest - but either way, testing will get a refresh (it's not working well, as you noticed) - and we will have Next Gen support very soon either through this PR, or some other way, really soon |
|
Hey @exzos28 👋 Thanks for putting this together, and for the genuinely thorough test plan. The overall shape here is what I'd want: build-time selection rather than runtime, legacy staying the default so nobody's upgrade silently changes SDKs, dual source sets, and the classpath exclusion because the two SDKs collide on the same Java package. That last one is a constraint we'd otherwise have found out the hard way, so thank you for working it through. One correction I think we need before this can land, and I want to be crystal clear about it because it's the load-bearing part. The PR rejects Ad Manager ad unit IDs under next-gen, on the basis that next-gen has no Ad Manager equivalent. According to Google's docs, Ad Manager is supported. There's a full Ad Manager next-gen documentation tree, for example the quick start and combining native + banner. If I'm reading it right, what's actually gone is the separate This matters more than a normal review nit because Ad Manager publishers are a meaningful share of this library's users, and for them a next-gen path that refuses their unit IDs isn't opt-in, it's unusable. Fair warning on process, since I don't want you sinking more time into rework blind: we have a larger piece of work going on with this library internally right now, and next-gen Android behind the existing JS API is part of it. I'll come back here with a concrete answer on whether we take this as-is with the Ad Manager fix, take the mechanism and build on it, or land it another way. Either way, the app.json / Expo config flag design and the source-set split are the parts I expect to keep, and I'll credit the work. One more thing worth flagging because it will bite someone eventually: per Google's migration guide, next-gen works only with no mediation or with AdMob as the mediation platform. Apps hosting mediation elsewhere can't use next-gen at all. Probably worth a line in Thanks again. Cheers |
GMA Next-Gen SDK has no separate AdManagerAdRequest/AdManagerAdView - Ad Manager unit IDs load through the same AdRequest.Builder as AdMob ones, so rejecting them here was incorrect.
Ad Manager native ad units load through the same NativeAdRequest as AdMob ones under GMA Next-Gen SDK - there is no dedicated Ad Manager request/view type to justify rejecting them.
GMA Next-Gen SDK's AdView/BannerAdRequest load Ad Manager and AdMob unit IDs the same way, so rejecting "/" prefixed unit IDs was wrong.
No caller rejects Ad Manager unit IDs anymore, so this helper and its now-inaccurate doc comment are dead weight.
Ad Manager unit IDs work fine under next-gen (see the android module fixes), so there's no longer a reason to gate these demos behind googleMobileAdsSdk !== 'next-gen'.
Ad Manager is supported under next-gen through the same request builders as AdMob - the real constraint is mediation (AdMob-only or none), not Ad Manager.
|
Hi @mikehardy Thanks for the careful read, and yeah, you're right. I went back and checked against the actual SDK rather than assuming, and the rejection was wrong - Ad Manager unit IDs go through the exact same builders as AdMob ones, no separate classes needed. Dropped the gate, wired the GAM-only fields through properly, and un-hid the Ad Manager demos in the example app that I'd gated off for no reason. Good call on the mediation note too - added a line about that to the docs page. |
|
Quick update - tested on a real emulator against the actual GAM test units:
|
|
Separately: happy to help set up proper e2e testing for this repo if that's useful, the current jet-based setup seems to have some issues. |
Adds an opt-in Android build path against Google's newer GMA Next-Gen SDK (ads-mobile-sdk), selected via a
google_mobile_ads_sdkapp.json flag (orgoogleMobileAdsSdkExpo config-plugin parameter). Defaults to the existing legacy SDK (play-services-ads), so existing apps are unaffected.android/src/legacyandandroid/src/nextgen, selected at build time via a Gradle.play-services-adsfrom the classpath when next-gen is selected, since both SDKs ship classes in the same Java package and cannot coexist.mobileAds().googleMobileAdsSdkso JS can detect which SDK variant is active (e.g. to hide Ad Manager specific UI).Description
Google is pushing a rewritten Mobile Ads SDK for Android as the eventual successor to
play-services-ads. It's a from-scratch package with no Ad Manager support and its own set of API quirks, so this isn't a drop-in swap — it's wired up as an alternative build target you opt into, with the legacy SDK staying the default.The two SDKs can't be linked into the same app (same Java package, different classes), which is why this is a build-time choice rather than a runtime one.
Related issues
#864
#850
#836
Release Summary
Adds opt-in Android support for Google's GMA Next-Gen SDK via a
google_mobile_ads_sdkapp.json flag.Checklist
and followed the process outlined there for submitting PRs.
AndroidiOSe2etests added or updated in__tests__e2e__jesttests added or updated in__tests__Test Plan
Built and installed both variants (
legacydefault and-PgoogleMobileAdsSdk=next-gen) on a real emulator. Confirmed via logcat that next-gen actually initializes and talks to Google's ad servers, and manually loaded real test ads for interstitial, rewarded, banner and native under both. Ad Manager unit IDs get rejected with a clear error under next-gen; regular AdMob unit IDs for the same formats work normally under both.yarn tests:jestandyarn tsc:compilepass. iOS wasn't built locally (no Xcode in this environment) — the only iOS change is a smallconstantsToExportaddition, worth having CI confirm.