Tauri v2 · Android & iOSv0.2.0

Google AdMob para tus apps Tauri v2

Banners nativos fuera del WebView, intersticiales, rewarded, flujo de consentimiento Google UMP y App Tracking Transparency de iOS — todo detrás de una única API de TypeScript fuertemente tipada con errores y eventos estructurados.

Instalación
npm add tauri-plugin-ad2mob
cargo add tauri-plugin-ad2mob
métodos
23
métodos
eventos
22
eventos
códigos de error
9
códigos de error
plataformas
2
plataformas
9:41

Mi App

Tauri v2 · Android / iOS

Anuncio

Banner nativo de AdMob

AdView / GADBannerView · adaptive

320×50

Banner nativo sobre el WebView — nunca dentro del DOM

Introducción

Características

Un plugin comunitario independiente que une Google Mobile Ads, Google UMP y ATT de iOS en una sola superficie coherente para Tauri v2.

Banners nativos

AdView / GADBannerView reales colocados sobre el borde del WebView — jamás renderizados en el DOM. Conscientes de safe areas: status bar, navigation bar y home indicator.

Intersticiales y rewarded

Máquinas de estado explícitas load → ready → show → closed con consultas is*Ready() y destroy explícito. La recompensa llega del callback real del SDK, nunca sintetizada.

Privacidad primero

Flujo de consentimiento Google UMP y ATT de iOS integrados. Las peticiones de anuncios se rechazan con CONSENT_REQUIRED mientras el estado UMP sea «required».

API fuertemente tipada

AdMobError con códigos estables, mapa de eventos tipado y tipos que reflejan uno a uno los modelos de Rust. TypeScript estricto de punta a punta.

22 eventos estructurados

Cada callback del SDK se reenvía como evento namespaced admob://* con payload tipado. AdMob.on() elige automáticamente el canal correcto en móvil y escritorio.

Seguro en escritorio

El crate compila para Windows, macOS y Linux; toda operación móvil devuelve un UNSUPPORTED_PLATFORM controlado. Tu build de escritorio no cambia.

Introducción

Instalación

Cuatro pasos: instalar los paquetes, registrar el plugin en Rust, conceder la capability y configurar los App ID de cada plataforma. Todo lo demás (SDKs nativos, keep-rules de R8, SPM de iOS) se resuelve automáticamente.
1

Instala los paquetes

Terminal
npm add tauri-plugin-ad2mob
# también disponible en: pnpm · bun · yarn
cargo add tauri-plugin-ad2mob

Peer dependency

El paquete de TypeScript depende de @tauri-apps/api ^2.0.0, que ya tendrás instalado en cualquier proyecto Tauri v2.
2

Registra el plugin en Rust

src-tauri/src/lib.rs
fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_ad2mob::init())
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

Opcionalmente puedes inicializar en el arranque con configuración inline — equivalente a la sección plugins > admob de tauri.conf.json:

Configuración inline
.plugin(tauri_plugin_ad2mob::init_with_config(serde_json::json!({
    "isTesting": true,
    "initializeOnStartup": true,
})))
3

Concede la capability

src-tauri/capabilities/default.json
{
  "permissions": [
    "ad2mob:default"
  ]
}

¿Por qué un único permiso?

ad2mob:default habilita todos los comandos, incluidos los listeners de eventos que usa AdMob.on(). Los anuncios no son una superficie sensible: el plugin nunca expone sistema de archivos, red ni capacidades del dispositivo al WebView.
4

Configura los App ID por plataforma

Android

Añade el meta-data del App ID dentro de <application> en gen/android/app/src/main/AndroidManifest.xml (crea el proyecto Android con tauri android init). El plugin valida el App ID en runtime y falla con INVALID_CONFIGURATION si falta.

AndroidManifest.xml
<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY" />

Desarrollo

Usa el App ID de pruebas de Google ca-app-pub-3940256099942544~3347511713 mientras desarrollas. Los SDK de Google Mobile Ads (24.x) y UMP (3.x) se enlazan automáticamente desde el módulo Gradle del plugin.

iOS

⚠️ iOS — en desarrollo activo

Las instrucciones siguientes describen la integración final y son correctas, pero iOS todavía no está disponible: su job de CI permanece temporalmente muteado mientras se resuelve un problema de empaquetado SwiftPM.

Añade estas claves al Info.plist (vía gen/apple o Xcode). Los frameworks GoogleMobileAds 13.x y UMP 3.x se resuelven con Swift Package Manager desde ios/Package.swift al generar el proyecto Xcode.

Info.plist
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY</string>
<key>NSUserTrackingUsageDescription</key>
<string>Your data will be used to show you more relevant ads.</string>

Desarrollo

App ID de pruebas de Google para iOS: ca-app-pub-3940256099942544~1458002511. Para publicar en el App Store recuerda además declarar ATT y los identificadores de publicidad en tus respuestas de App Privacy, y añadir los SKAdNetworkItems de Google.

Introducción

Inicio rápido

Con la instalación lista, estos son los primeros cinco minutos de tu app con anuncios. Suscríbete a los eventos antes de inicializar y gestionar anuncios para no perderte ninguno.
main.ts — flujo completo
import { AdMob } from "tauri-plugin-ad2mob"

// 1. Detecta soporte e inicializa (idempotente)
if (await AdMob.isSupported()) {
  await AdMob.initialize({ isTesting: true })
}

// 2. Configura tus Ad Unit IDs de producción
await AdMob.configure({
  adUnitIds: {
    banner: "ca-app-pub-XXXXXXXXXXXXXXXX/YYYYYYYYYY",
    interstitial: "ca-app-pub-XXXXXXXXXXXXXXXX/YYYYYYYYYY",
    rewarded: "ca-app-pub-XXXXXXXXXXXXXXXX/YYYYYYYYYY",
  },
})

// 3. Suscríbete a eventos ANTES de operar
await AdMob.on("admob://rewarded-earned", ({ payload }) => {
  console.log("Recompensa:", payload.amount, payload.type)
})

// 4. Muestra un banner nativo
await AdMob.showBanner({ position: "bottom", size: "adaptive" })

Inicialización desde tauri.conf.json

Si prefieres no llamar a initialize() en tu código, activa initializeOnStartup en la configuración del plugin: el SDK se inicializa solo cuando la app arranca, con el mismo AdMobConfig.

src-tauri/tauri.conf.json
{
  "plugins": {
    "admob": {
      "isTesting": true,
      "debug": true,
      "initializeOnStartup": true
    }
  }
}

initialize() es idempotente

Llamarlo otra vez es un no-op seguro que devuelve el estado actual — nunca reejecuta el flujo nativo del SDK. Usa AdMob.configure() para cambiar los Ad Unit IDs.

Privacidad

Consentimiento con Google UMP

El plugin integra el User Messaging Platform de Google y normaliza su estado a cuatro valores predecibles. Mientras el estado sea required, toda petición de anuncios se rechaza con CONSENT_REQUIRED — los anuncios nunca se piden sin consentimiento.
Flujo de consentimiento
const { status } = await AdMob.requestConsent()
// status: "unknown" | "required" | "notRequired" | "obtained"

const current = await AdMob.getConsentStatus()
EstadoSignificado¿Se pueden pedir anuncios?
unknownAún no se ha consultado el estado UMP.No — CONSENT_REQUIRED
requiredEl usuario debe completar el formulario de consentimiento.No — CONSENT_REQUIRED
notRequiredNo se requiere consentimiento para esta ubicación/configuración.
obtainedEl usuario completó el formulario de consentimiento.

No persistas el consentimiento tú mismo

El SDK de UMP lo guarda por dispositivo. Con automaticallyRequestConsent: true (por defecto) el flujo ya se ejecuta durante initialize(); solo llama requestConsent() manualmente si lo desactivaste o quieres ofrecer un botón de «opciones de privacidad».

Privacidad

App Tracking Transparency (iOS)

ATT nunca se solicita de forma automática. Pídelo desde un gesto del usuario o activa requestTrackingAuthorization: true en initialize() para mostrar el prompt justo después del arranque.
App Tracking Transparency
const status = await AdMob.requestTrackingAuthorization()
// iOS:        "notDetermined" | "restricted" | "denied" | "authorized"
// Android y escritorio: "notAvailable" — seguro de llamar sin condiciones

const known = await AdMob.getTrackingAuthorizationStatus()

Requisito de Info.plist

El prompt de ATT solo aparece si existe la clave NSUserTrackingUsageDescription en el Info.plist (ver Instalación → iOS). Además solo se muestra una vez por instalación; reinstala o restablece los ajustes de privacidad del simulador para verlo de nuevo.

Anuncios

Intersticial

Anuncio a pantalla completa con una máquina de estados explícita: carga, consulta de disponibilidad, muestra y liberación. Todos los métodos son seguros frente a concurrencia — el estado pasa por un Mutex y las cargas obsoletas nunca corrompen el estado.
Ciclo de vida del intersticial
await AdMob.loadInterstitial()   // resuelve cuando el anuncio está cargado

if (await AdMob.isInterstitialReady()) {
  await AdMob.showInterstitial() // resuelve cuando el usuario lo cierra
}

await AdMob.destroyInterstitial() // libera el anuncio cargado, si lo hay
loadInterstitial()isInterstitialReady()showInterstitial()admob://interstitial-closedrecargar

Los anuncios se consumen

Cada show consume el anuncio. Recarga después de cada evento *-closed. Si llamas show sin carga previa, la promesa rechaza con AD_NOT_READY; fallos del SDK llegan como LOAD_FAILED / SHOW_FAILED con el detalle en el evento *-failed.

Anuncios

Rewarded

Anuncios con recompensa cuya entrega viene del callback real del SDK (OnUserEarnedRewardListener en Kotlin, GADRewardedAdDelegate en Swift). Cerrar el anuncio sin completarlo emite admob://rewarded-closed — pero jamás una recompensa.
Recompensas verificables
const unlisten = await AdMob.on("admob://rewarded-earned", ({ payload }) => {
  // payload: { adUnitId?, amount, type } — callback REAL del SDK
  grantReward(payload.amount, payload.type)
})

await AdMob.loadRewarded()
if (await AdMob.isRewardedReady()) {
  await AdMob.showRewarded() // resuelve cuando el usuario lo cierra
}

// cuando ya no lo necesites:
// unlisten()

Nunca otorgues recompensas desde rewarded-closed

La recompensa solo se emite desde admob://rewarded-earned, que proviene del listener nativo del SDK mientras el usuario está viendo el anuncio. Confiar en el evento de cierre permitiría cobrar premios sin ver el anuncio.

Referencia

Eventos

Los 22 eventos del plugin, con nombres estables y payloads estructurados. Suscríbete con AdMob.on(evento, handler) antes de inicializar para no perderte ninguno. El campo stage distingue fallos de carga ("load") de fallos de muestra ("show") — los eventos de banner lo omiten.
EventoTipo de payloadCampos
admob://initializedInitializedEventplatform, testing
admob://consent-changedConsentChangedEventstatus
admob://tracking-authorization-changedTrackingAuthorizationChangedEventstatus

Referencia

API pública

Los 23 métodos del objeto AdMob, agrupados por área. Todos son seguros de llamar sin condiciones: en escritorio, las operaciones de anuncios rechazan con UNSUPPORTED_PLATFORM mientras el núcleo (initialize, configure, getStatus, destroy y consultas de estado) sigue funcionando.

Núcleo

AdMob.initialize(options?: AdMobConfig)Promise<InitializationResult>

Inicializa el SDK de Google Mobile Ads. Es idempotente: llamarlo de nuevo es un no-op seguro que devuelve el estado actual. Con isTesting: true los Ad Unit IDs que falten se resuelven automáticamente a los oficiales de Google.

ParámetroTipoDescripción
options.appIdstringApp ID genérico para ambas plataformas.
options.androidAppIdstringApp ID para Android (prioridad sobre appId).
options.iosAppIdstringApp ID para iOS (prioridad sobre appId).
options.isTestingbooleanModo desarrollo: resuelve test IDs oficiales.
options.initializeOnStartupbooleanInicializa al arrancar desde tauri.conf.json.
options.requestTrackingAuthorizationbooleanSolo iOS: pide ATT tras inicializar.
options.automaticallyRequestConsentbooleanEjecuta el flujo UMP durante la inicialización. Por defecto true.
options.debugbooleanLogs detallados del plugin. Sin datos personales.
ErroresINVALID_CONFIGURATIONNATIVE_ERROR
initialize
const result = await AdMob.initialize({
  appId: "ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY",
  isTesting: true,
})
// { initialized: true, platform: "android", testing: true }
AdMob.configure(options: ConfigureOptions)Promise<void>

Configura los Ad Unit IDs a nivel de aplicación (se fusionan sobre los valores previos). Orden de resolución de cualquier ID: argumento explícito → configure() → test IDs de Google si isTesting → error INVALID_CONFIGURATION.

ParámetroTipoDescripción
options.adUnitIds.bannerstringAd Unit ID para banners.
options.adUnitIds.interstitialstringAd Unit ID para intersticiales.
options.adUnitIds.rewardedstringAd Unit ID para rewarded.
ErroresINVALID_ARGUMENT
configure
await AdMob.configure({
  adUnitIds: {
    banner: "ca-app-pub-XXXXXXXXXXXXXXXX/YYYYYYYYYY",
    interstitial: "ca-app-pub-XXXXXXXXXXXXXXXX/YYYYYYYYYY",
    rewarded: "ca-app-pub-XXXXXXXXXXXXXXXX/YYYYYYYYYY",
  },
})
AdMob.isSupported()Promise<boolean>

Devuelve true en Android e iOS, false en Windows, macOS y Linux. Úsalo para omitir la lógica de anuncios en escritorio.

isSupported
if (!(await AdMob.isSupported())) return
// solo llega aquí en móvil
AdMob.getStatus()Promise<AdMobStatus>

Instantánea del estado completo del plugin: inicialización, plataforma, modo test, consentimiento, ATT y disponibilidad de cada formato.

getStatus
const status = await AdMob.getStatus()
// { initialized, platform, testing, consentStatus, trackingStatus,
//   interstitialReady, rewardedReady, bannerVisible }
AdMob.destroy()Promise<void>

Limpieza global: libera el banner, el intersticial y el rewarded, elimina los recursos nativos y resetea el estado para poder volver a inicializar.

destroy
await AdMob.destroy() // libera todos los recursos de anuncios

Privacidad

AdMob.requestConsent()Promise<ConsentResult>

Ejecuta el flujo de Google UMP: actualiza la información de consentimiento y muestra el formulario solo si es necesario. Mientras el estado sea required, las peticiones de anuncios rechazan con CONSENT_REQUIRED.

ErroresUNSUPPORTED_PLATFORMNATIVE_ERROR
requestConsent
const { status } = await AdMob.requestConsent()
if (status === "obtained") {
  // consentimiento listo, los anuncios pueden pedirse
}
AdMob.getConsentStatus()Promise<ConsentStatus>

Último estado UMP conocido: unknown, required, notRequired u obtained.

getConsentStatus
const status = await AdMob.getConsentStatus()
AdMob.requestTrackingAuthorization()Promise<TrackingAuthorizationStatus>

Muestra el prompt de ATT de iOS. En Android y escritorio resuelve "notAvailable" sin lanzar error, así que es seguro llamarlo sin condiciones. Nunca se solicita de forma automática salvo que lo actives en initialize().

requestTrackingAuthorization
const status = await AdMob.requestTrackingAuthorization()
if (status === "authorized") {
  // el usuario permite el rastreo: mejor eCPM
}
AdMob.getTrackingAuthorizationStatus()Promise<TrackingAuthorizationStatus>

Último estado ATT conocido, sin mostrar ningún prompt.

getTrackingAuthorizationStatus
const status = await AdMob.getTrackingAuthorizationStatus()

Banner

AdMob.showBanner(options?: ShowBannerOptions)Promise<void>

Carga y muestra un banner nativo. Por defecto position: "bottom" y size: "adaptive". La promesa resuelve cuando el anuncio está cargado y visible; un evento banner-failed significa que nada se adjuntó.

ParámetroTipoDescripción
options.adUnitIdstringAd Unit ID; si se omite se usa el configurado o el de test.
options.position"top" | "bottom"Borde de la ventana donde se ancla el banner.
options.sizeBannerSizeUno de los seis tamaños soportados; adaptive por defecto.
ErroresNOT_INITIALIZEDINVALID_CONFIGURATIONINVALID_ARGUMENTLOAD_FAILEDCONSENT_REQUIREDUNSUPPORTED_PLATFORM
showBanner
await AdMob.showBanner({ position: "bottom", size: "adaptive" })
AdMob.hideBanner()Promise<void>

Oculta el banner sin destruirlo: puedes volver a mostrarlo con showBanner() sin recargar.

ErroresNOT_INITIALIZEDUNSUPPORTED_PLATFORM
hideBanner
await AdMob.hideBanner()
AdMob.isBannerVisible()Promise<boolean>

true cuando el banner nativo está visible en este momento.

isBannerVisible
const visible = await AdMob.isBannerVisible()
AdMob.setBannerPosition(options: SetBannerPositionOptions)Promise<void>

Mueve un banner a la posición indicada sin recargar el anuncio.

ParámetroTipoDescripción
options.positionrequerido"top" | "bottom"Nueva posición del banner.
ErroresINVALID_ARGUMENTNOT_INITIALIZED
setBannerPosition
await AdMob.setBannerPosition({ position: "top" })
AdMob.destroyBanner()Promise<void>

Destruye el banner nativo y libera sus recursos. Llama a showBanner() de nuevo para crear otro.

ErroresNOT_INITIALIZEDUNSUPPORTED_PLATFORM
destroyBanner
await AdMob.destroyBanner()

Intersticial

AdMob.loadInterstitial(options?: LoadAdOptions)Promise<void>

Carga un intersticial; la promesa resuelve cuando el anuncio está listo para mostrarse. Puede tardar segundos en conexiones lentas.

ParámetroTipoDescripción
options.adUnitIdstringAd Unit ID opcional; si se omite se usa el configurado o el de test.
ErroresNOT_INITIALIZEDINVALID_CONFIGURATIONINVALID_ARGUMENTLOAD_FAILEDCONSENT_REQUIREDUNSUPPORTED_PLATFORM
loadInterstitial
await AdMob.loadInterstitial()
AdMob.showInterstitial()Promise<void>

Muestra un intersticial previamente cargado. La promesa resuelve cuando el usuario lo cierra. Rechaza con AD_NOT_READY si no hay nada cargado.

ErroresAD_NOT_READYSHOW_FAILEDNOT_INITIALIZEDCONSENT_REQUIREDUNSUPPORTED_PLATFORM
showInterstitial
if (await AdMob.isInterstitialReady()) {
  await AdMob.showInterstitial()
}
AdMob.isInterstitialReady()Promise<boolean>

true cuando hay un intersticial cargado y listo para mostrar.

isInterstitialReady
const ready = await AdMob.isInterstitialReady()
AdMob.destroyInterstitial()Promise<void>

Destruye el intersticial cargado, si lo hay.

destroyInterstitial
await AdMob.destroyInterstitial()

Rewarded

AdMob.loadRewarded(options?: LoadAdOptions)Promise<void>

Carga un anuncio rewarded; resuelve cuando está listo para mostrarse.

ParámetroTipoDescripción
options.adUnitIdstringAd Unit ID opcional; si se omite se usa el configurado o el de test.
ErroresNOT_INITIALIZEDINVALID_CONFIGURATIONINVALID_ARGUMENTLOAD_FAILEDCONSENT_REQUIREDUNSUPPORTED_PLATFORM
loadRewarded
await AdMob.loadRewarded()
AdMob.showRewarded()Promise<void>

Muestra el rewarded cargado. Resuelve cuando el usuario lo cierra; la recompensa llega por el evento admob://rewarded-earned desde el callback real del SDK.

ErroresAD_NOT_READYSHOW_FAILEDNOT_INITIALIZEDCONSENT_REQUIREDUNSUPPORTED_PLATFORM
showRewarded
if (await AdMob.isRewardedReady()) {
  await AdMob.showRewarded()
}
AdMob.isRewardedReady()Promise<boolean>

true cuando hay un rewarded cargado y listo para mostrar.

isRewardedReady
const ready = await AdMob.isRewardedReady()
AdMob.destroyRewarded()Promise<void>

Destruye el rewarded cargado, si lo hay.

destroyRewarded
await AdMob.destroyRewarded()

Eventos

AdMob.on(E extends AdMobEventName>(event: E, handler: (payload: AdMobEventMap[E]) => void)Promise<Unlisten>

Suscribe un handler a un evento del plugin y devuelve una función unlisten awaitable. El mapa de eventos es totalmente tipado: el payload se infiere del nombre del evento. En móvil usa el canal de eventos del plugin; en escritorio, el sistema global.

ParámetroTipoDescripción
eventrequeridoAdMobEventNameNombre del evento, p. ej. "admob://rewarded-earned".
handlerrequerido(payload) => voidCallback tipado según AdMobEventMap.
on
const unlisten = await AdMob.on("admob://rewarded-earned", ({ payload }) => {
  console.log("+" + payload.amount, payload.type)
})

// para desuscribirse:
// await unlisten()

Referencia

Tipos

Cada tipo público refleja uno a uno los modelos de Rust (src/models.rs) y forma parte de la API estable del plugin. Estos son los principales; el resto se exporta desde tauri-plugin-ad2mob.
types.ts (extracto)
// Configuración — misma forma que "plugins > ad2mob" en tauri.conf.json
export interface AdMobConfig {
  appId?: string              // App ID genérico
  androidAppId?: string       // prioridad sobre appId en Android
  iosAppId?: string           // prioridad sobre appId en iOS
  isTesting?: boolean         // resuelve los test IDs oficiales de Google
  initializeOnStartup?: boolean
  requestTrackingAuthorization?: boolean // solo iOS, tras initialize
  automaticallyRequestConsent?: boolean  // por defecto: true
  debug?: boolean             // logs detallados; sin datos personales
}

export interface AdUnitIds {
  banner?: string
  interstitial?: string
  rewarded?: string
}

export interface ShowBannerOptions {
  adUnitId?: string
  position?: BannerPosition   // "top" | "bottom"
  size?: BannerSize
}

export interface LoadAdOptions {
  adUnitId?: string           // si se omite: configure() → test IDs
}

// Instantánea de estado que devuelve getStatus()
export interface AdMobStatus {
  initialized: boolean
  platform: AdMobPlatform
  testing: boolean
  consentStatus: ConsentStatus
  trackingStatus: TrackingAuthorizationStatus
  interstitialReady: boolean
  rewardedReady: boolean
  bannerVisible: boolean
}

// Recompensa real entregada por el SDK en admob://rewarded-earned
export interface Reward {
  amount: number
  type: string
}

// Cada método rechaza con un AdMobError (subclase de Error) con "code" estable
export class AdMobError extends Error {
  readonly code: AdMobErrorCode
}

export function isAdMobError(error: unknown): error is AdMobError
Unión de literalesValores
BannerPosition"top" | "bottom"
BannerSize"banner" | "largeBanner" | "mediumRectangle" | "fullBanner" | "leaderboard" | "adaptive"
ConsentStatus"unknown" | "required" | "notRequired" | "obtained"
TrackingAuthorizationStatus"notDetermined" | "restricted" | "denied" | "authorized" | "notAvailable"
AdMobPlatform"android" | "ios" | "windows" | "macos" | "linux"
AdMobErrorCodeNOT_INITIALIZED · AD_NOT_READY · LOAD_FAILED · SHOW_FAILED · INVALID_CONFIGURATION · INVALID_ARGUMENT · CONSENT_REQUIRED · UNSUPPORTED_PLATFORM · NATIVE_ERROR

Referencia

Errores

Cada método lanza un AdMobError — una subclase de Error — con un campo code estable y compartido con el enum de errores de Rust. Usa isAdMobError() como type guard.
Manejo de errores
import { AdMob, isAdMobError } from "tauri-plugin-ad2mob"

try {
  await AdMob.showInterstitial()
} catch (error) {
  if (isAdMobError(error) && error.code === "AD_NOT_READY") {
    await AdMob.loadInterstitial()
  }
}
CódigoCuándo ocurreQué hacer
NOT_INITIALIZEDOperación de anuncios antes de initialize().Inicializa el plugin al arrancar la app.
INVALID_CONFIGURATIONFalta o es inválido el App ID, un Ad Unit ID o la configuración de plataforma.Revisa el manifest / Info.plist y configure().
INVALID_ARGUMENTArgumentos malformados.Revisa tipos y valores de las opciones.
AD_NOT_READYshow*() sin anuncio cargado.Carga primero y recarga tras cada cierre.
LOAD_FAILEDEl SDK no pudo cargar el anuncio.Mira el evento *-failed y reintenta con backoff.
SHOW_FAILEDEl SDK no pudo presentar el anuncio.Mira el evento *-failed (stage: show) y reintenta.
CONSENT_REQUIREDEl estado UMP es required.Ejecuta requestConsent() y completa el formulario.
UNSUPPORTED_PLATFORMAPI de móvil usada en escritorio.Filtra con isSupported() si quieres omitir en silencio.
NATIVE_ERRORCualquier otro error reportado por la capa nativa.Inspecciona message y los eventos asociados.

Producción

Pruebas y anuncios de test

Con isTesting: true, los Ad Unit IDs que falten se resuelven a los oficiales de Google. Estos son los IDs explícitos si prefieres fijarlos a mano (App IDs de test: Android ~3347511713, iOS ~1458002511).
FormatoAndroidiOS
Bannerca-app-pub-3940256099942544/6300978111ca-app-pub-3940256099942544/2934735716
Intersticialca-app-pub-3940256099942544/1033173712ca-app-pub-3940256099942544/441146891
Rewardedca-app-pub-3940256099942544/5224354917ca-app-pub-3940256099942544/1717083536

Emuladores y simuladores

Los emuladores de Android funcionan con los test IDs; el simulador de iOS también. Para validación final necesitas dispositivo real: el comportamiento de UMP y el prompt de ATT pueden diferir entre simulador y hardware.

Nunca hagas clic en tus propios anuncios

Los test IDs son solo para desarrollo y pruebas automatizadas. Hacer clic en anuncios de producción propios viola las políticas de AdMob y puede supender tu cuenta.

Dispositivos de prueba con anuncios reales

En dispositivos Android con Google Play services puedes registrar tu dispositivo como test device (testDeviceIds via MobileAds.setRequestConfiguration) para recibir anuncios de prueba con tus Ad Unit IDs reales.

Producción

Comportamiento en escritorio

El crate compila para Windows, macOS y Linux sin enlazar el runtime de WebView de escritorio: añadir el plugin no cambia las dependencias de tu build de escritorio. Toda la superficie móvil degrada de forma controlada.
APIComportamiento en Windows / macOS / Linux
initialize()No-op correcto: el estado se registra y se emite admob://initialized.
configure(), getStatus(), isSupported() y consultas de estadoFuncionan con normalidad.
requestTrackingAuthorization()Resuelve notAvailable sin lanzar error.
requestConsent() y toda operación de anunciosRechazan con UNSUPPORTED_PLATFORM.
destroy()No-op correcto.

Patrón recomendado

if (await AdMob.isSupported()) {
  await AdMob.initialize({ isTesting: true })
}

Producción

Solución de problemas

Los doce síntomas más comunes, su causa y su solución rápida.

Producción

Limitaciones conocidas

Documentadas con honestidad para que no te sorprendan en producción.
  • El banner superpone el WebView en lugar de redimensionarlo: reserva espacio en tu UI.
  • Un showBanner mientras otra carga está en curso reemplaza el banner anterior; la promesa sustituida rechaza con LOAD_FAILED.
  • Los anuncios a pantalla completa de iOS conservan su promesa de show pendiente a través de destroy(), para que el SDK pueda reportar el cierre: la promesa siempre termina resolviéndose o rechazándose.
  • La mediación se soporta en la medida del SDK base de Google Mobile Ads; el plugin no configura adaptadores por red.
  • El código nativo Android/iOS está validado por revisión y tests unitarios de lógica pura: ejecuta la app de ejemplo (examples/admob-demo) en hardware real antes de publicar.