Skip to content
Sunstone Apps
← Back to blog
React Native Ads

AdMob UMP in React Native: privacy messages are not just console setup

Publishing privacy messages in AdMob only helps when the app is also wired to request, honor, and reopen consent through the UMP SDK.

Published: 9 min read
OpenGraph preview image for this article. AdMob UMP in React Native: privacy messages are not just console setup

AdMob privacy setup feels like console work until the first release candidate tells a different story.

You create the app in AdMob, add units, publish GDPR, link Play — and the build may still not be ready to request ads. The missing piece is rarely a hidden console setting. It is the contract between AdMob, the User Messaging Platform SDK, and the point in startup where the app decides whether ad requests are allowed.

This article comes from the Android release path for Daily Sudoku: Offline Puzzle, Expo/React Native with react-native-google-mobile-ads. The details are Sudoku-specific; the failure mode is common: real ad unit IDs and an app that is blocked, limited, or privacy-incomplete because messages were treated as paperwork instead of runtime behavior.

This is not legal advice. It is engineering: where that decision happens in the app.

The three systems involved

Three separate systems. Flatten them into one vague “AdMob is configured” label and you fix the wrong layer.

AdMob app record — Android app ID, ad units, Play listing link, ad serving review. While that review is pending, the console shows preparing, under review, or limited. That is not an SDK integration bug.

Privacy & messaging — GDPR, US state privacy messages, and other surfaces, per app and region. Publishing means AdMob has a message available. It does not mean every build will show it automatically.

App runtime — In React Native, the Google Mobile Ads SDK through react-native-google-mobile-ads. That code asks UMP for consent, shows forms when required, and blocks or allows requests based on the result.

The console defines what can be shown; the app decides when it can request ads.

What the release flow needed

For the Sudoku app, the release setup only became trustworthy after these checks were true at the same time:

  • The Android package in Google Play was com.sunstoneapps.dailysudoku.
  • The AdMob app used the production Android app ID, not the public Google test app ID.
  • Banner, interstitial, and rewarded placements had production ad unit IDs.
  • app-ads.txt was published on the public app domain.
  • The Play Store listing was linked from AdMob after it became visible.
  • GDPR messaging was published for the Android app.
  • A US state privacy message was published for the Android app.
  • The native app called UMP before the first ad request.
  • The app disabled ads when UMP said requests were not allowed.

Each line catches a different failure class. A missing Play link keeps review pending. A missing message makes UMP report no configured form. A missing runtime gate lets ad requests fire before consent is known. A wrong native app ID is worst: perfect JavaScript, manifest quietly pointing at a test application.

That is why release validation inspects config and generated native output. JavaScript ad unit IDs are not the whole AdMob configuration.

GDPR messages: published is not the finish line

The European message is the one most mobile developers think about first. In AdMob it appears under Privacy & messaging as the European regulations flow. For a small app, the default Google-managed message is often enough to start: it asks for consent, offers privacy options, and lets users refuse.

But the console status only says that AdMob has a message ready. The app still needs to:

  1. call UMP during startup or before the first ad request;
  2. read whether ads can be requested;
  3. avoid initializing or requesting ads when the result says no;
  4. expose a way to reopen privacy options later when required.

In the Sudoku app, the important behavior is not that there is a menu label called “Ads privacy options”. The important behavior is that the native implementation calls AdsConsent.gatherConsent(), then reads AdsConsent.getConsentInfo(), then turns that result into a small state object:

type AdsPrivacyState = {
  canRequestAds: boolean;
  privacyOptionsRequired: boolean;
};

That state feeds the app-level ad config. If canRequestAds is false, the app swaps to a disabled ads configuration. This keeps the rest of the game simple. Screens and placements do not need to know all of UMP. They only see whether ads are available.

This gate is more valuable than defensive checks scattered around every banner or rewarded placement.

US state privacy messages are a different job

The US state privacy message is not a second GDPR form. It answers a different requirement: users in supported US states can opt out of the sale or sharing of personal information. In AdMob, the current flow lets the publisher target all currently supported and future supported US states.

For a global Android app available in the United States, creating that message is a conservative compliance step. It is not a monetization feature. It will not raise eCPM by itself. It can even reduce personalized ad value for users who opt out.

The benefit is not eCPM. It is an explicit path for honoring privacy choices where law requires them — better than incomplete config and hoping the SDK interprets the blank space correctly.

For the Sudoku app, the published US message had these properties:

  • message name: Daily Sudoku - US States Privacy - Android;
  • app: Daily Sudoku: Offline Puzzle;
  • language: en-US;
  • geography: all supported US states, current and future;
  • status: published.

The console also warned that UMP must be integrated in the app and that propagation can take up to one hour. That warning is easy to dismiss, but it is exactly the point: the message is only useful when the app uses the SDK.

App store linking and AdMob review

Linking the Play Store listing to the AdMob app is another separate step. It can only happen once the listing is discoverable enough for AdMob to find it by package or URL. Before that, the AdMob app may show that the store is not linked, even when ad units exist and traffic is already reaching the account.

After linking, AdMob reviews the app to decide whether it is ready to serve ads normally. The console may say that review usually takes two to three days and that ad serving is limited until it is complete.

That limited state should not be debugged as if it were a React Native rendering issue. It is an external review state. The right action is to confirm that the app is linked, privacy messages are published, policies are clean, and the app itself does not block gameplay when ads are unavailable.

For a game, this distinction matters. A no-fill result, a review-pending state, and a UMP-required state all lead to “no ad shown” from the player’s point of view. They do not have the same cause.

Non-personalized ads are a product choice

One subtle point in this setup: the app can request non-personalized ads only, even after consent. That is a valid product choice when the team wants a simpler privacy posture, but it is not neutral for monetization.

In react-native-google-mobile-ads, placement requests can pass:

requestNonPersonalizedAdsOnly: true;

That keeps the ad request conservative. It also means the app should not expect the same monetization profile as a setup that requests personalized ads where allowed. Privacy configuration and monetization strategy are connected. A consent form does not automatically improve revenue; it creates the conditions under which the app can make compliant ad requests.

If the goal is better revenue, the follow-up work is not “create more messages”. It is to decide whether personalized ads are allowed in some regions, how that choice is represented in the app, and how the analytics distinguish no-fill, consent-denied, request-disabled, and review-limited cases.

A release checklist that catches real failures

For an Expo/React Native Android app using AdMob, the useful checklist is:

  1. Confirm the production AdMob Android app ID in native config.
  2. Confirm all production ad unit IDs in the app environment/config.
  3. Confirm app-ads.txt is published on the domain used by the Play listing.
  4. Link the Play Store listing in AdMob after the listing becomes discoverable.
  5. Publish the GDPR message for the Android app.
  6. Publish the US state privacy message if the app serves users in the United States.
  7. Call UMP before the first ad request.
  8. Gate the ad provider with canRequestAds.
  9. Expose privacy options in settings when the SDK says they are required.
  10. Treat no-fill as inventory unless logs show an integration error.
  11. Validate on a real release build, not only in local debug. (We wrote about why __DEV__ is false in release builds and how to gate dev tools by config — the same lesson applies to UMP consent dialogs.)

This checklist is split across console, code, and runtime on purpose. Fixing only the console without changing the app gate is the most common trap.

The simple path is what survives release

The implementation that survives release is not clever. It is a small privacy state, one startup call, one settings row, and one ad config gate.

That plain shape is what makes it testable. The app can mock canRequestAds: false and verify that ads are disabled. It can mock privacy options being required and verify that settings shows the management button. It can keep reward logic separate so a failed or canceled rewarded ad never grants gameplay benefits.

The AdMob console will still have waiting periods: review in days, a new message up to an hour to propagate, no-fill on a real request. None of that should block a game or make the team treat pending review as a layout bug.

A message published in AdMob only matters when the app executes the contract — policy, platform, and runtime in the same flow.

Contact Sunstone Apps