Skip to content

Commit 4f005fd

Browse files
committed
docs: add v17 migration and troubleshooting guide
1 parent 03cd78f commit 4f005fd

13 files changed

Lines changed: 332 additions & 61 deletions

.spellcheck.dict.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,12 @@ PooledAd
262262
refill
263263
refills
264264
poll
265+
stringly
266+
applovin
267+
fail-to-show
268+
fail-to-present
269+
SHOW_FAILED
270+
v16
271+
v18
272+
npm
273+
AdMob-only

docs.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
["Impression-level ad revenue", "/impression-level-ad-revenue"],
2323
["Revenue telemetry and auction diagnostics", "/revenue-telemetry-and-auction-diagnostics"],
2424
["Preload pools and multi-format recipes", "/preload-pools-and-multiformat-recipes"],
25+
["v17 API reference", "/rngma-v17-api-reference"],
2526
["Video ad volume control", "/video-ad_volume-control"],
2627
["Testing", "/testing"]
2728
]
@@ -31,7 +32,8 @@
3132
[
3233
["Migrating to v5", "/migrating-to-v5"],
3334
["Migrating to v6", "/migrating-to-v6"],
34-
["Migrating to v15", "/migrating-to-v15"]
35+
["Migrating to v15", "/migrating-to-v15"],
36+
["Migrating to v17", "/migrating-to-v17"]
3537
]
3638
]
3739
]

docs/common-reasons-for-ads-not-showing.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,5 @@ Some private DNS providers can block ads from displaying. If your device or emul
108108

109109
- Mobile Ads SDK [iOS](https://developers.google.com/admob/ios/quick-start), [Android](https://developers.google.com/admob/android/quick-start)
110110
- [Common reasons for ads not showing](https://support.google.com/admob/answer/9469204)
111+
- [Migrating to v17](/migrating-to-v17) — structured errors, no-fill vs failure, diagnostics
112+
- [Revenue telemetry and auction diagnostics](/revenue-telemetry-and-auction-diagnostics)`ResponseInfo` after load

docs/displaying-ads-hook.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,7 @@ telemetry. See [Revenue telemetry and auction diagnostics](/revenue-telemetry-an
9898
To warm fullscreen inventory and poll at show time (instead of a one-shot hook), see
9999
[Preload pools and multi-format recipes](/preload-pools-and-multiformat-recipes).
100100

101+
Upgrading from v16? See [Migrating to v17](/migrating-to-v17) for structured errors,
102+
`destroy()` ownership, and the positional-hook deprecation.
103+
101104
[Impression-level ad revenue]: /impression-level-ad-revenue

docs/displaying-ads.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ app has been completed, or game over). The ads can be preloaded in the backgroun
6767

6868
To keep a **buffer** of ready interstitials and poll at show time, see
6969
[Preload pools and multi-format recipes](/preload-pools-and-multiformat-recipes).
70+
For `destroy()`, structured errors, and other v17 deltas, see
71+
[Migrating to v17](/migrating-to-v17).
7072

7173
To create a new interstitial, call the `createForAdRequest` method from the `InterstitialAd` class. The first argument
7274
of the method is the "Ad Unit ID". For testing, we can use a Test ID, however for production the ID from the

docs/mediation.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ To configure mediation in the AdMob UI, complete the following steps:
1818
For the Google Mobile Ads SDK to communicate with third-party ad networks, you need to include a mediation adapter for each network in your app. Each
1919
adapter must be integrated in the Android and iOS layer of your application.
2020

21+
Some third-party networks also ship as scoped npm packages under
22+
`@react-native-google-mobile-ads/<network>` (optional; install only what you mediate).
23+
See [Migrating to v17](/migrating-to-v17#optional-scoped-mediation-adapter-packages).
24+
2125
To choose the adapters you want to install, see Integrate open source and versioned adapters
2226
([Android](https://developers.google.com/admob/android/choose-networks#integrate_open-source_and_versioned_adapters) | [iOS](https://developers.google.com/admob/ios/choose-networks#integrate_open-source_and_versioned_adapters)).
2327

docs/migrating-to-v17.mdx

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
# Migrating to v17
2+
3+
v17 keeps classic create / load / show and `<BannerAd>` / `NativeAd` **source-compatible**.
4+
Most apps need no rewrite to keep ads loading and showing. New surfaces are **opt-in**:
5+
structured errors, `ResponseInfo`, `destroy()`, fullscreen hook options, preload pools,
6+
multi-format requests, and scoped mediation adapter packages.
7+
8+
Use this guide for the deltas publishers hit on upgrade, plus honest troubleshooting.
9+
Canonical TypeScript shapes live in the
10+
[v17 API reference](./rngma-v17-api-reference.md).
11+
12+
## What stays the same
13+
14+
| Area | Guidance |
15+
| ----------------------------- | ------------------------------------------------------------------------ |
16+
| Class names and call shapes | `InterstitialAd.createForAdRequest`, `load()`, `show()`, event listeners |
17+
| Banner / native components | Existing props and load paths keep working |
18+
| Legacy error `code`/`message` | Unchanged string values on existing paths |
19+
| Consent / request config | Same entry points; a few additive optional fields |
20+
21+
You can upgrade, ship, and adopt new APIs later.
22+
23+
## Checklist
24+
25+
1. Upgrade `react-native-google-mobile-ads` and rebuild native apps (pods / Gradle).
26+
2. Keep using create / load / show until you need a new surface.
27+
3. Prefer branching on structured `reason` / `phase` (and hook `status`) over legacy `code` strings.
28+
4. Call `destroy()` (or let hooks / `release()` ownership rules do it) when you finish with an ad.
29+
5. Optionally adopt telemetry, pools, multi-format, or scoped adapter packages — see below.
30+
31+
## Additive: `ResponseInfo` and paid telemetry
32+
33+
After a successful load, read `responseInfo` on the ad (or hook / multi-format handle).
34+
Load failures — including clean **no-fill** — may carry the same record on
35+
`error.responseInfo` (or top-level on multi-format results).
36+
37+
Paid events expose a **compact** snapshot (`PaidResponseInfo`) without the full
38+
`adapterResponses` list. Public paid field names use `currency` (not native
39+
`currencyCode`) and optional `valueMicros` as a decimal string.
40+
41+
```ts
42+
import { AdEventType, InterstitialAd, TestIds } from 'react-native-google-mobile-ads';
43+
44+
const ad = InterstitialAd.createForAdRequest(TestIds.INTERSTITIAL);
45+
46+
ad.addAdEventListener(AdEventType.LOADED, () => {
47+
console.log(ad.responseInfo?.loadedAdapterResponse?.adSourceName);
48+
});
49+
50+
ad.addAdEventListener(AdEventType.ERROR, error => {
51+
// Routine no-fill still has reason 'no-fill' and may include responseInfo.
52+
console.log(error.reason, error.phase, error.responseInfo?.responseId);
53+
});
54+
55+
ad.load();
56+
```
57+
58+
Full recipes:
59+
[Revenue telemetry and auction diagnostics](/revenue-telemetry-and-auction-diagnostics).
60+
61+
## Additive: structured errors (`reason` + `phase`)
62+
63+
Every structured failure carries:
64+
65+
| Field | Role |
66+
| --------------- | ---------------------------------------------------------------------- |
67+
| `code` | Legacy string (**deprecated** in v17; prefer `reason`; removed in v18) |
68+
| `message` | Human-readable text |
69+
| `reason` | Stable machine reason (`no-fill`, `network-error`, …) |
70+
| `phase` | `'load'` or `'show'` |
71+
| `responseInfo?` | Auction record when the platform attached one |
72+
73+
There is **no** `SHOW_FAILED` event. Fail-to-show arrives as `AdEventType.ERROR` with
74+
`phase: 'show'`. On Android, presentation failures that previously emitted nothing now
75+
emit that single `ERROR` — filter on `phase` so load and show outcomes stay distinct.
76+
77+
```ts
78+
ad.addAdEventListener(AdEventType.ERROR, error => {
79+
if (error.phase === 'show') {
80+
// Presentation failed; do not treat as a load/no-fill.
81+
return;
82+
}
83+
if (error.reason === 'no-fill' || error.reason === 'mediation-no-fill') {
84+
// Routine empty response — retry or continue without treating as a crash.
85+
return;
86+
}
87+
console.warn('load failure', error.reason, error.message);
88+
});
89+
```
90+
91+
On fullscreen hooks that use the options form, use **`status`** (not `error !== null`) to
92+
tell routine `'no-fill'` from `'error'`. Details:
93+
[Revenue telemetry and auction diagnostics](/revenue-telemetry-and-auction-diagnostics)
94+
(section “Distinct no-fill vs failure”).
95+
96+
## Additive: lifecycle — `destroy()`, ownership, impression
97+
98+
Fullscreen and native ads expose idempotent `destroy()`: it releases JS listeners and
99+
asks native to drop the holder. Destroyed instances ignore late events and further show
100+
attempts.
101+
102+
```ts
103+
const unsub = ad.addAdEventListener(AdEventType.CLOSED, () => {
104+
unsub();
105+
ad.destroy();
106+
});
107+
```
108+
109+
**Ownership rules that bite in production**
110+
111+
| Situation | Do this |
112+
| --------------------------------------------- | -------------------------------------------------------------------------- |
113+
| Imperative create / load / show | You own `destroy()` when finished |
114+
| Options-form fullscreen hook | Hook cleans up on unmount / identity change; prefer leaving it alone |
115+
| `usePooledAd` / `useMultiFormatAd` still owns | **Do not** call `destroy()` — call `release()` first if you need ownership |
116+
| After `release()` | You own `destroy()` and any staleness check |
117+
| Pool `poll()` filled result | Ownership transferred; destroy the held ad when done |
118+
119+
`AdEventType.IMPRESSION` is additive (no payload). Hooks also expose an `impression`
120+
boolean on the options-form result.
121+
122+
Reload after `CLOSED` or fail-to-show reuses the same request id once native holders
123+
auto-evict — you do not need a new class instance solely because the previous show ended.
124+
125+
## Fullscreen hooks: positional form deprecated
126+
127+
Passing an options object opts into the v17 result (`status`, `autoLoad`, structured
128+
`error`). The positional form still works, is **deprecated in v17**, and is **removed in
129+
v18**.
130+
131+
```tsx
132+
// Before (deprecated)
133+
const { isLoaded, load, show, error } = useInterstitialAd(unit);
134+
useEffect(() => {
135+
if (consentReady) load();
136+
}, [consentReady, load]);
137+
138+
// After
139+
const { status, show, error } = useInterstitialAd({
140+
adUnitId: unit,
141+
autoLoad: consentReady,
142+
});
143+
```
144+
145+
| Positional | Options form |
146+
| --------------------------- | ------------------------------------------------- |
147+
| `isLoaded` | `status === 'loaded'` |
148+
| `isShowing` | `status === 'showing'` |
149+
| `isClosed` | `status === 'closed'` |
150+
| `error?: Error` | `error: AdError \| null` + `'no-fill'` status arm |
151+
| `load` / `show` / `destroy` | Same, plus `retry` |
152+
153+
`autoLoad` is a load **policy**, not a second placement identity. Setting it `false`
154+
stops future automatic loads; it does not cancel an in-flight request (platforms do not
155+
expose load cancellation). See [Displaying Ads via Hook](/displaying-ads-hook).
156+
157+
Automatic loading does **not** re-fire after `'closed'`. Call `load()` / `retry()` (or
158+
flip `autoLoad` with a new consent-ready value) when you want the next ad.
159+
160+
## Optional: pools and multi-format
161+
162+
Warm inventory and native-or-banner competitive requests are opt-in. Prefer presets —
163+
do not hand-roll capability matrices.
164+
165+
| Need | Guide |
166+
| ----------------------------------- | -------------------------------------------------------------------------------- |
167+
| Fullscreen pool + poll at show time | [Preload pools and multi-format recipes](/preload-pools-and-multiformat-recipes) |
168+
| Count-1 native **or** GAM banner | Same guide · `MultiFormatAdPresets.nativeOrBanner` |
169+
| Types, expiry, ownership | [v17 API reference](./rngma-v17-api-reference.md#ad-pools-new) |
170+
171+
## Optional: scoped mediation adapter packages
172+
173+
Third-party network adapters ship as separate packages under
174+
`@react-native-google-mobile-ads/<network>` (for example `applovin`, `facebook`,
175+
`unity`). Install only the networks you mediate; they are **not** required for AdMob-only
176+
apps. Follow [Mediation](/mediation) for AdMob UI setup and native wiring.
177+
178+
## Troubleshooting
179+
180+
### Ads still load, but analytics / retries look wrong
181+
182+
| Symptom | Likely cause / fix |
183+
| ---------------------------------------------- | ----------------------------------------------------------------------------- |
184+
| Treating every `error !== null` as a hard fail | Options-form hooks populate `error` on `'no-fill'` too — branch on `status` |
185+
| Looking for `SHOW_FAILED` | Does not exist — use `ERROR` with `phase: 'show'` |
186+
| Android never saw show failures before | Expected — Android now emits one `ERROR` (`phase: 'show'`) on fail-to-present |
187+
| Paid payload missing `currencyCode` | Public field is `currency` |
188+
| Full waterfall missing on every paid event | By design — use load-time `ResponseInfo` for waterfalls; paid is compact |
189+
190+
### Destroy / ownership surprises
191+
192+
| Symptom | Likely cause / fix |
193+
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- |
194+
| Hook still reports filled after you called `destroy()` | Destroyed hook-owned inventory — `release()` first, or let the hook destroy |
195+
| Post-show events never fire after pooled show | Hook-owned show destroys on show-promise settle — `release()` before show if you need `CLOSED` / reward |
196+
| Late `LOADED` after a newer `load()` / `destroy()` | Stale generation — ignored by design; do not treat as a second fill |
197+
198+
### Hooks and pools
199+
200+
| Symptom | Likely cause / fix |
201+
| ----------------------------------------------------- | ---------------------------------------------------------------------------- |
202+
| Options-form hook stuck on `'idle'` | `autoLoad` is false — confirm echoed `autoLoad` on the result |
203+
| Next ad never warms after dismissal | Automatic load does not re-fire after `'closed'` — call `load()` / `retry()` |
204+
| `useAdPool` / `usePooledAd` stuck on `absent` / empty | `poolId` typo or missing `AdPoolProvider` entry |
205+
| Two screens starve a depth-1 pool | Two `usePooledAd(sameId)` owners competing |
206+
| Positional `useInterstitialAd(unit)` struck through | Deprecated — pass an options object |
207+
208+
### Fill and setup (unchanged)
209+
210+
Account approval, new units, test devices, and `applicationId` issues still dominate
211+
“no ads” reports. See
212+
[Common reasons for ads not showing](/common-reasons-for-ads-not-showing) and
213+
[Ad Inspector](/ad-inspector).
214+
215+
### Diagnostics dump for issue reports
216+
217+
| Kind of bug | Include |
218+
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
219+
| Classic load / show / fill | Ad Inspector outcome, ad unit, test device, platform SDK version |
220+
| Auction / mediation mix | Summarized load-time `ResponseInfo` ([Revenue telemetry](/revenue-telemetry-and-auction-diagnostics)) |
221+
| Pools / multi-format / preload | `JSON.stringify(getAdCapabilities(), null, 2)` ([Preload pools diagnostics](/preload-pools-and-multiformat-recipes#diagnostics-dump)) |
222+
| Structured error handling | `reason`, `phase`, `code`, `message`, and whether `responseInfo` was present |
223+
224+
## What this guide does not cover
225+
226+
- Removing shims or dropping deprecated positional hooks (**v18**)
227+
- Multi-count requests (`numberOfAds` / `requestCount` &gt; 1)
228+
- Mediation **host** SDKs (MAX, CloudX, …) — out of this package surface
229+
- Invented eCPM / lift helpers — not part of the public API
230+
231+
## Related guides
232+
233+
- [Revenue telemetry and auction diagnostics](/revenue-telemetry-and-auction-diagnostics)
234+
- [Preload pools and multi-format recipes](/preload-pools-and-multiformat-recipes)
235+
- [Displaying Ads](/displaying-ads)
236+
- [Displaying Ads via Hook](/displaying-ads-hook)
237+
- [Mediation](/mediation)
238+
- [Common reasons for ads not showing](/common-reasons-for-ads-not-showing)
239+
- [Migrating to v15](/migrating-to-v15) — prior Android Kotlin floor note
240+
- [v17 API reference](./rngma-v17-api-reference.md) — types, migration sketches, first failure modes

docs/preload-pools-and-multiformat-recipes.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,5 +352,6 @@ many deep pools will clamp. Read `pool.resolved.effectiveBufferSize` after creat
352352
- [Native Ads](/native-ads) — standalone native layouts
353353
- [Revenue telemetry and auction diagnostics](/revenue-telemetry-and-auction-diagnostics)
354354
`responseInfo` / paid events on load and poll
355+
- [Migrating to v17](/migrating-to-v17) — upgrade checklist, ownership, troubleshooting
355356
- [v17 API reference](./rngma-v17-api-reference.md#ad-pools-new) — pool / multi-format types,
356357
expiry, and ownership rules

docs/revenue-telemetry-and-auction-diagnostics.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,5 @@ analytics by default.
212212
- [Mediation](/mediation) — adapter installation
213213
- [Common reasons for ads not showing](/common-reasons-for-ads-not-showing) — account and setup fill issues
214214
- [Preload pools and multi-format recipes](/preload-pools-and-multiformat-recipes) — warm inventory and GAM native-or-banner loads
215+
- [Migrating to v17](/migrating-to-v17) — upgrade deltas, errors, lifecycle, troubleshooting
215216
- [v17 API reference](./rngma-v17-api-reference.md#7-response-metadata-and-paid-events) — canonical types

0 commit comments

Comments
 (0)