Web-app dev4, Google AdMob (Banner and Interstitial ads)

This writing is about how to apply Google AdMob into mobile application. I included Banner and Interstitial ads in my React Native Web-view application.

This is continued writing from previous one. 


1. Register your application in AdMob



  • AdMob account need some verification from Google and this will be done normally within few days.


2. React Native Banner ads

  • First run the command: npm i react-native-google-mobile-ads

  • Check your app ID in AdMob. Go to your app - app setting, then you can see app ID as below.

  • Put your app ID in app.json as below. The app ID should be out of "expo": {}.
,  "react-native-google-mobile-ads": {
    "android_app_id": "ca-app-pub-111111111~1111111111111"
  }


  • In App.js, import components to show Banner ads.
import { BannerAd, BannerAdSize, TestIds } from 'react-native-google-mobile-ads';


  • Go to AdMob, Apps - Ad units - Add ad unit. And add Banner ad unit as below.


  • Check your Banner ad ID as below.

  • Include your Banner ad ID in App.js as below.
const BannerAdUnitId = __DEV__ ? TestIds.BANNER : 'ca-app-pub-111111111111/111111111111';


  • Now we need to decide where to show Banner ads. I will show my Banner ads in bottom 10% and the rest 90% for Webview.
  • Note that JSX expression must have exactly only one outermost element! So I have 1 parent element, which is styles.container and separate 2 child elements for Webview and Banner ads.
return (
    <View style={styles.container}>

      <View style={ {width: '100%', height: '90%'}}>
        <WebView
        source={{ uri: 'https://expo.dev' }}
      />
      </View>
      <View style={{width:'100%', height: '10%'}}>
        <BannerAd
          unitId={BannerAdUnitId}
          size={BannerAdSize.ANCHORED_ADAPTIVE_BANNER}
          requestOptions={{
            requestNonPersonalizedAdsOnly: true,
          }}
      />
      </View>
      
    </View>
    )
  • Now everything is ready for Banner ads and it's time to test if Banner appears well. When you test it use Demo ad units' ID. If you use your ad ID for test, it can affect to profit and it is regarded as invalid activity by AdMob. If it happens several times, your AdMob account can be suspended.
  • Banner Demo ID is: ca-app-pub-3940256099942544/9214589741
  • For detail refer to: https://developers.google.com/admob/android/test-ads#java
const BannerAdUnitId = __DEV__ ? TestIds.BANNER : 'ca-app-pub-3940256099942544/9214589741';


  • If you test it with development build as previous step (edit eas.json for development build and run command: eas build --profile development --platform android), then you will see how Banner ads appears.
  • If you test it with development build, you would see below error, which says Property 'View' doesn't exist.

  • This is because core component, <View> was not imported so it shows such error. Edit App.js to import View and save App.js, then it will show result as soon as you save it. You will see Banner Test ad appears at bottom side well.
import { View, StyleSheet } from 'react-native';



3. React Native Interstitial ads

  • As in the Banner ads, run the command: npm i react-native-google-mobile-ads, put your app ID in app.json.
  • Go to AdMob, Apps - Ad units - Add ad unit. And add Interstitial ad unit as below.


    • Check your Interstitial ad ID as below.

    • Include your Interstitial ad ID in App.js as below.
    const InterstitialAdUnitId = __DEV__ ? TestIds.INTERSTITIAL : 'ca-app-pub-2222222222/2222222222';
    


    • Import the necessary components in App.js as below. For the Interstitial ad, I will use useEffect and useState hook, so I add necessary library for it too.
    import { InterstitialAd, AdEventType } from 'react-native-google-mobile-ads';
    import { useEffect, useState } from 'react';
    


    • As below, add the createForAdRequest method from the InterstitialAd class. Argument of this method is Interstitial ad ID.
    const interstitial = InterstitialAd.createForAdRequest(InterstitialAdUnitId, {
      requestNonPersonalizedAdsOnly: true,
    });
    


    • I will show Interstitial ad as soon as ad is ready (loaded). And I want it to appear just 1 time. 
      const [loaded, setLoaded] = useState(false);
    
      useEffect(() => {
        const unsubscribe = interstitial.addAdEventListener(AdEventType.LOADED, () => {
          setLoaded(true);
          interstitial.show();
        });
    
        // Start loading the interstitial straight away
        interstitial.load();
    
        // Unsubscribe from events on unmount
        return unsubscribe;
      }, []);
    
      // No advert ready to show yet
      if (!loaded) {
        return null;
      }
    


    • Above code will flow like this:
      1. Initial state of 'loaded' is 'false'.
      2. When Interstitial ad is not loaded yet, it will return null.
      3. When Interstitial ad is loaded, it will set 'loaded' to true and show Interstitial ad.
      4. When user gets out of Interstitial ad, it will return Webview and Banner ad. (Interstitial ad will not be loaded and shown again, because dependency of useEffect is empty array [ ], which means this is executed only at first rendering.)
    const InterstitialAdUnitId = __DEV__ ? TestIds.INTERSTITIAL : 'ca-app-pub-3940256099942544/1033173712';
    


    • Testing it with development build will be shown as below. Interstitial test ad is shown well and when closed, Webview and Banner test ad is also shown well.



    • For your information, I made my application like above at the beginning, but I found out that when network speed was very low, then my app showed null screen for long time because interstitial ad loading took long. (Because, as mentioned, my coding flows like first interstitial should appear and then Webview can appear.) So I changed to show splash image instead of null while ad loading as below.
      // No advert ready to show yet
      if (!loaded) {
        return (
          <View style={styles.container}>
            <Image 
              style={styles.image}
              source={require('./assets/splash.png')} />
          </View>
          );
      } 
    

    • The whole App.js to test the AdMob ad would be as below.
    import { WebView } from 'react-native-webview';
    import Constants from 'expo-constants';
    import { View, StyleSheet } from 'react-native';
    import { BannerAd, BannerAdSize, TestIds } from 'react-native-google-mobile-ads';
    import { InterstitialAd, AdEventType } from 'react-native-google-mobile-ads';
    import { useEffect, useState } from 'react';
    import 'expo-dev-client';
    
    const BannerAdUnitId = __DEV__ ? TestIds.BANNER : 'ca-app-pub-3940256099942544/9214589741';
    const InterstitialAdUnitId = __DEV__ ? TestIds.INTERSTITIAL : 'ca-app-pub-3940256099942544/1033173712';
    
    const interstitial = InterstitialAd.createForAdRequest(InterstitialAdUnitId, {
      requestNonPersonalizedAdsOnly: true,
    });
    
    export default function App() {
    
      const [loaded, setLoaded] = useState(false);
    
      useEffect(() => {
        const unsubscribe = interstitial.addAdEventListener(AdEventType.LOADED, () => {
          setLoaded(true);
          interstitial.show();
        });
    
        // Start loading the interstitial straight away
        interstitial.load();
    
        // Unsubscribe from events on unmount
        return unsubscribe;
      }, []);
    
      // No advert ready to show yet
      if (!loaded) {
        return (
          <View style={styles.container}>
            <Image 
              style={styles.image}
              source={require('./assets/splash.png')} />
          </View>
          );
      }
    
    
      return (
        <View style={styles.container}>
    
          <View style={ {width: '100%', height: '90%'}}>
            <WebView
            source={{ uri: 'https://expo.dev' }}
          />
          </View>
          <View style={{width:'100%', height: '10%'}}>
            <BannerAd
              unitId={BannerAdUnitId}
              size={BannerAdSize.ANCHORED_ADAPTIVE_BANNER}
              requestOptions={{
                requestNonPersonalizedAdsOnly: true,
              }}
          />
          </View>
    
        </View>
        )
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        marginTop: Constants.statusBarHeight,
      },
    });
    



    Comments

    Mostly viewed post

    Web-app dev1, Web development and robots.txt