Crear anuncio recompensado (Reward) con react-native-google-mobile-ads para React Native y Expo

Tiempo de lectura: 3 minutos

Hoy vamos a aprender cómo podemos implementar un anuncio recompensando de Google Admob (Reward) en React Native con Expo.

Pexels ads

Lo primero que haremos es instalar la libreria de anuncios:

npm install react-native-google-mobile-ads

Debemos tener una cuenta registrada en Admob.

Si usamos Expo tenemos que añadir dentro de app.config.js o app.json lo siguiente:

{
  "expo": {
    "plugins": [
      [
        "react-native-google-mobile-ads",
        {
          "androidAppId": "ca-app-pub-xxxxxxxx~xxxxxxxx",
          "iosAppId": "ca-app-pub-xxxxxxxx~xxxxxxxx"
        }
      ]
    ]
  }
}

Y tenemos que instalar:

npx expo install expo-build-properties

Y si usamos solo React Native lo añadimos de esta forma:

// <project-root>/app.json
{
  "react-native-google-mobile-ads": {
    "android_app_id": "ca-app-pub-xxxxxxxx~xxxxxxxx",
    "ios_app_id": "ca-app-pub-xxxxxxxx~xxxxxxxx"
  }
}

Para que se aplique al proyecto tenemos que poner:

# For iOS
npx pod-install
npx react-native run-ios

# For Android
npx react-native run-android

NOTA: A mi solo me ha funcionado con la forma de React Native, luego he tenido que añadir a mano esto en Android.manifest:

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

*Recuerda indicar el ID de aplicación ADMOB en el hueco de ca-app-pub-xxxxxxxx~xxxxxxxx

Ahora crearemos el bloque de anuncios recompensados. Lo llamamos Rewarded.tsx

import { getIdVideosBonificados } from "./util/IDS_anuncios";
import { useState, useEffect, FC } from "react";
import mobileAds, { RewardedAd, RewardedAdEventType } from 'react-native-google-mobile-ads';

const rewarded = RewardedAd.createForAdRequest(getIdVideosBonificados());

interface Props {
    onRewardEarned?: (reward: { type: string, amount: number }) => void;
}

var setLoadAd: (load: boolean) => void = () => {};

// Componente para gestionar el anuncio recompensado
const Rewarded: FC<Props> = ({ onRewardEarned }) => {
    const [loaded, setLoaded] = useState(false);

    // Configuramos `setLoadAd` para iniciar el proceso de carga cuando se invoque `initLoadRewardedAds`.
    setLoadAd = () => rewarded.load();

    useEffect(() => {
        // Inicializamos los anuncios y cargamos el anuncio recompensado al iniciar el componente
        mobileAds()
            .initialize()
            .then(() => {
                console.log("MobileAds initialized successfully");
                rewarded.load();
            })
            .catch(error => console.error("Failed to initialize MobileAds", error));
    }, []);

    useEffect(() => {
        // Escuchar eventos de carga completa del anuncio y recompensa obtenida
        const unsubscribeLoaded = rewarded.addAdEventListener(RewardedAdEventType.LOADED, () => {
            console.log("Anuncio cargado");
            setLoaded(true);
        });

        const unsubscribeEarned = rewarded.addAdEventListener(
            RewardedAdEventType.EARNED_REWARD,
            reward => {
                console.log('Recompensa obtenida', reward);
                if (onRewardEarned) {
                    console.log('Invocando onRewardEarned'); // Agrega este log
                    onRewardEarned(reward);
                }
            },
        );

        return () => {
            unsubscribeLoaded();
            unsubscribeEarned();
        };
    }, [onRewardEarned]);

    // Mostrar anuncio al completar la carga
    useEffect(() => {
        if (loaded) {
            rewarded.show();
            setLoaded(false); // Reiniciar el estado de carga después de mostrar el anuncio
        }
    }, [loaded]);

    return null;
};

export default Rewarded;

// Función para iniciar la carga de anuncios recompensados
export function initLoadRewardedAds() {
    setLoadAd(true);
}

Y ahora tenemos que crear otro objeto que nos permitirá obtener el ID correspondiente a iOS / Android.

/util/IDS_anuncios.tsx

import { Platform } from "react-native";

var test = true;

export const publisherId = Platform.select({
    ios: "pub-XXXXXX",
    android: "pub-XXXXXX",
});

export const adAppId = Platform.select({
    ios: "ca-app-pub-XXXXXXXXXXXX",
    android: "ca-app-pub-XXXXXXXXXXXX",
});

export function getIdVideosBonificados() {//Anuncio bonificado 
    if (!test) {
        //Si es IOS o Android
        var bannerId = Platform.OS === 'ios' ? "ca-app-pub-XXXXXXXXXXXXXXXXXXX/XXXXXXX" : "ca-app-pub-XXXXXXXXXXXXX/XXXXXXX";
    } else { //Anuncio de prueba
        bannerId = "ca-app-pub-3940256099942544/5224354917";
    }
    return bannerId;
}

El código de anuncio de prueba es:

ca-app-pub-3940256099942544/5224354917

En este código debes incluir tu código real para iOS y Android de anuncio tipo Rewarded (Bonificado). También es compatible con Rewarded Interstitial.

Y ahora para utilizarlo haremos lo siguiente:

En la pantalla que queramos implementarlo:

 ...

import Rewarded, { initLoadRewardedAds } from './Rewarded';

const [desactivarBotonRecompensa, setDesactivarBotonRecompensa] = useState(false);


const handleLoadAd = () => {
    initLoadRewardedAds();
    setDesactivarBotonRecompensa(true);
  };

  const handleRewardEarned = (reward: { type: string; amount: number }) => {
    //MANEJAR LA RECOMPENSA
    manejar_recompensa();
    setDesactivarBotonRecompensa(false);
  };



 return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>

      <button
      disabled={desactivarBotonRecompensa}
      onClick={() => {
          handleLoadAd();
      }}
      style={{
        backgroundColor: desactivarBotonRecompensa ? '#ccc' : 'primary',
        color: 'white',
      }}
    >
      <span style={{ marginRight: '8px', verticalAlign: 'middle' }}>🎬</span>
      Mirar un video recompensado
    </button>

      {desactivarBotonRecompensa && (
        <Rewarded onRewardEarned={handleRewardEarned} />
      )}

    </View>
  );

 ...

Hemos importado el componente.

Se inicializa initLoadRewardedAds() esto, carga un anuncio y lo muestra en cuanto lo tiene disponible.

Después hemos creado un estado que indicará que el anuncio está cargando o no.

Una vez recompensado se obtiene en handleRewardEarned = (reward: { type: string; amount: number }) indicará el tipo de recompensa obtenida y el valor. Ahora puedes manejarlo cómo necesites.

En el render de componentes hemos creado un botón para abrir el vídeo recompensado, cada vez que se abra cargará un vídeo nuevo.

Finalmente importamos la vista correspondiente al bloque de anuncio.

Deja un comentario