Using AdMob rewarded videos in your Expo project

Drew Sindle
The Startup

--

While using the latest Expo SDK (v33.0.0) I came across an issue with AdMob rewarded videos, specifically the event listeners. In this tutorial I will show you how to correctly implement rewarded video ads in your project.

Getting Started

This assumes you have node installed and have expo-cli installed. My current node version is v11.1.0 and my expo-cli version is v2.20.2

Overview:

  1. Creating a new project
  2. Adding the new expo-ads-admob package
  3. Configure a rewarded ad

1. Creating a new project

expo init admob-reward-tutorial

For this tutorial we will use a blank template. Enter a name and slug, it doesn’t really matter here. If yarn is installed it will ask if you’d like to use Yarn to install dependencies, I currently do not use Yarn with Expo but it is up to you.

Move into your newly created project directory:

cd admob-reward-tutorial

Start the project to verify everything is working:

expo start

Use a simulator or the Expo app on your phone to make sure everything is working. You should see this:

Expo starter screen

2. Adding AdMob package to your project

In Expo sdk v33.0.0 they are depreciating most named imports from the Expo package and instead wanting you to install the packages individually. Stop the expo cli and run:

npm install expo-ads-admob

3. Configuring a rewarded video

We’ll setup a simple component to render a button. Create a new file named ‘AdMobRewardedComponet.js’ and create the boilerplate for a component:

import React, { Component } from "react";export default class AdMobRewardedComponent extends Component {render() {return null;}}

Import the component into your app.js:

import React from ‘react’;import { StyleSheet, View } from ‘react-native’;import AdMobRewardedComponent from ‘./AdMobRewardedComponet’export default function App() {return (<View style={styles.container}><AdMobRewardedComponent/></View>);};const styles = StyleSheet.create({container: {flex: 1,backgroundColor: ‘#fff’,alignItems: ‘center’,justifyContent: ‘center’,},});

Now we’ll create a simple button and attach an onPress and link it to adMob. In your AdMobRewardedComponent import the following:

import { Button } from ‘react-native’import { AdMobRewarded } from ‘expo-ads-admob’;

First we’ll configure the AdMobRewarded import. We’ll start by setting the test device ID and ad unit ID in a componetDidMount function. Make sure to make the function async by adding the async tag in front (more about this later):

async componentDidMount() {AdMobRewarded.setTestDeviceID(‘EMULATOR’);AdMobRewarded.setAdUnitID(‘ca-app-pub-3940256099942544/5224354917’); // Test ID, Replace with your-admob-unit-id}

For testing purposes we’re using an emulator and set the testDeviceID as such. And since we are testing we need to be sure to use the test adUnitID which is above. Next we’ll create some listeners in the componentDidMount() function:

AdMobRewarded.addEventListener(‘rewardedVideoDidRewardUser’, () => console.log(‘Rewarded’));AdMobRewarded.addEventListener(‘rewardedVideoDidLoad’, () => console.log(‘VideoLoaded’));AdMobRewarded.addEventListener(‘rewardedVideoDidFailToLoad’, () => console.log(‘FailedToLoad’));AdMobRewarded.addEventListener(‘rewardedVideoDidOpen’, () => console.log(‘Opened’));AdMobRewarded.addEventListener(‘rewardedVideoDidClose’, () => console.log(‘Closed’));AdMobRewarded.addEventListener(‘rewardedVideoWillLeaveApplication’, () => console.log(‘LeaveApp’));AdMobRewarded.addEventListener(‘rewardedVideoDidStart’, () => console.log(‘Started’));

The last listener, ‘rewardedVideoDidStart’, was not in the Expo documentation and will cause an error later when we unmount and unsubscribe from the listeners. I’ve submitted a pull request to fix this, so hopefully by the time you read this it will be in the documentation!

We then would like to request an ad as soon as possible to make sure it’s loaded when we want to use it. Since it uses async to call we use await like so:

await AdMobRewarded.requestAdAsync();

The entire componetDidMount() function should now be:

async componentDidMount() {AdMobRewarded.setTestDeviceID(‘EMULATOR’);AdMobRewarded.setAdUnitID(‘ca-app-pub-3940256099942544/5224354917’); // Test ID, Replace with your-admob-unit-idAdMobRewarded.addEventListener(‘rewardedVideoDidRewardUser’, () => console.log(‘Rewarded’));AdMobRewarded.addEventListener(‘rewardedVideoDidLoad’, () => console.log(‘VideoLoaded’));AdMobRewarded.addEventListener(‘rewardedVideoDidFailToLoad’, () => console.log(‘FailedToLoad’));AdMobRewarded.addEventListener(‘rewardedVideoDidOpen’, () => console.log(‘Opened’));AdMobRewarded.addEventListener(‘rewardedVideoDidClose’, () => console.log(‘Closed’));AdMobRewarded.addEventListener(‘rewardedVideoWillLeaveApplication’, () => console.log(‘LeaveApp’));AdMobRewarded.addEventListener(‘rewardedVideoDidStart’, () => console.log(‘Started’));await AdMobRewarded.requestAdAsync();}

Under the componentDidMount() function we will create a componentWillUnmount() function to unsubscribe from the listeners:

componentWillUnmount() {AdMobRewarded.removeAllListeners();}

Next we’ll create our onPress function:

_handlePress = async () => {await AdMobRewarded.showAdAsync();}

Next we’ll create a button and a state to enable the button once the ad has loaded. Add the state:

state = {loadedAd: false,}

Import the button:

import { Button } from ‘react-native’

In the return of the render create a button and attach the onPress we created earlier:

render() {const { loadedAd } = this.state;return (<ButtononPress={this._handlePress}title=”Rewarded Video Ad”disabled={!loadedAd}/>)}

Edit the ‘rewardedVideoDidLoad’ listener to change state on load:

AdMobRewarded.addEventListener(‘rewardedVideoDidLoad’, () => {console.log(‘VideoLoaded’)this.setState({ loadedAd: true })});

You can delete the console.logs if you’d like, they’re just there to help development purposes. And lastly you can add a state change on the ‘rewardedVideoDidClose’ to disable the button after it has been closed:

AdMobRewarded.addEventListener(‘rewardedVideoDidClose’, () => {console.log(‘Closed’)this.setState({ loadedAd: false })});

And that’s it! When the component mounts, it will create the listeners, load the ad and when the ad is loaded the listener will enable the button to be able to watch it. Next you can add whatever code you like to the ‘rewardedVideoDidRewardUser’ listener.

The complete final code for the component:

import React, { Component } from “react”;import { Button } from “react-native”;import { AdMobRewarded } from “expo-ads-admob”;export default class AdMobRewardedComponent extends Component {state = {loadedAd: false};async componentDidMount() {AdMobRewarded.setTestDeviceID(“EMULATOR”);AdMobRewarded.setAdUnitID(“ca-app-pub-3940256099942544/5224354917”); // Test ID, Replace with your-admob-unit-idAdMobRewarded.addEventListener(“rewardedVideoDidRewardUser”, () =>console.log(“Rewarded”));AdMobRewarded.addEventListener(“rewardedVideoDidLoad”, () => {console.log(“VideoLoaded”);this.setState({ loadedAd: true });});AdMobRewarded.addEventListener(“rewardedVideoDidFailToLoad”, () =>console.log(“FailedToLoad”));AdMobRewarded.addEventListener(“rewardedVideoDidOpen”, () =>console.log(“Opened”));AdMobRewarded.addEventListener(“rewardedVideoDidClose”, () => {console.log(“Closed”);this.setState({ loadedAd: false });});AdMobRewarded.addEventListener(“rewardedVideoWillLeaveApplication”, () =>console.log(“LeaveApp”));AdMobRewarded.addEventListener(“rewardedVideoDidStart”, () =>console.log(“Started”));await AdMobRewarded.requestAdAsync();}componentWillUnmount() {AdMobRewarded.removeAllListeners();}_handlePress = async () => {await AdMobRewarded.showAdAsync();};render() {const { loadedAd } = this.state;return (<ButtononPress={this._handlePress}title=”Rewarded Video Ad”disabled={!loadedAd}/>);}}

--

--