Integrating AdMob in React Native Expo: A Comprehensive Developer's Guide

Are you looking to monetize your React Native Expo app? Google's AdMob is one of the most popular advertising platforms, and in this guide, I'll walk you through integrating different types of ads into your app.

Prerequisites

Before we start, make sure you have:

  • An existing React Native Expo project
  • An AdMob account
  • A Google Play Developer account (for Android)
  • Patience and attention to detail 😄

Step 1: Install Required Packages

You have two main options for implementing AdMob in your Expo project:

Option 1: Expo Ads AdMob

expo install expo-ads-admob
npm install @react-native-async-storage/async-storage

Option 2: React Native Google Mobile Ads

npm install react-native-google-mobile-ads
# If using Expo, also run:
expo install @react-native-async-storage/async-storage

Step 2: Set Up Google AdMob Account and Obtain Ad Unit IDs

Creating an AdMob Account

  1. Go to Google AdMob
  2. Sign in with your Google account
  3. Click "Get Started" or "Create Account"

Adding a New App

  1. Click "Apps" in the left sidebar
  2. Click the "Add app" button
  3. Choose your platform (iOS or Android)
  4. Select "I have an app" if your app is already published
    • If not published, select "I'm going to publish an app"
  5. Enter your app's name
  6. Select the platform (iOS/Android)

Creating Ad Units

  1. After adding your app, click on "Ad units" in the left sidebar
  2. Click "Add ad unit" button
  3. Choose the ad format:
    • Banner Ad: Recommended sizes: 320x50, 300x250, 468x60
    • Interstitial Ad: full-screen ads
    • Rewarded Ad: optional, for in-app rewards
  4. Name your ad unit descriptively (e.g., "Home Screen Banner", "Game Over Interstitial")
  5. Configure ad unit settings
  6. Click "Create"

Obtaining App and Ad Unit IDs

After creating an ad unit, you'll see two important IDs:

  • App ID: Starts with ca-app-pub- (used in app.json)
  • Ad Unit ID: Also starts with ca-app-pub- (used in your code)

Important Notes

  • Use different ad units for different platforms (iOS/Android)
  • In development, use test ad units
  • Replace test IDs with production IDs before publishing
  • Ensure your app complies with AdMob policies

Example ID Formats

  • App ID: ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy
  • Ad Unit ID: ca-app-pub-xxxxxxxxxxxxxxxx/zzzzzzzzzz

Configuring Test Devices

  1. Go to "Settings" > "Test devices"
  2. Add device IDs for testing to avoid account suspension
    • On Android, you can get the device ID from logcat when running your app
    • On iOS, use Xcode or device logs to find the device identifier

Expo Ads vs React Native Google Mobile Ads: Package Comparison

Expo Ads AdMob (expo-ads-admob)

Pros:

  • Direct integration with Expo
  • Easier setup for Expo-managed projects
  • Minimal configuration required
  • Lighter weight
  • Seamless with Expo workflows

Cons:

  • Limited to Expo-managed projects
  • Fewer advanced configuration options
  • Less frequent updates
  • Limited customization

React Native Google Mobile Ads (react-native-google-mobile-ads)

Pros:

  • More comprehensive AdMob features
  • Regularly updated by Google
  • Advanced configuration options
  • Works with bare React Native projects
  • More robust error handling
  • Better support for latest AdMob features
  • Supports mediation and advanced ad targeting

Cons:

  • More complex setup
  • Requires additional native module configuration
  • Slightly steeper learning curve
  • More manual configuration needed

Recommendation

  • For Expo-managed projects: Use expo-ads-admob
  • For bare React Native or more advanced projects: Use react-native-google-mobile-ads

Best Practice: If you anticipate ejecting from Expo or need advanced ad features, start with react-native-google-mobile-ads

Configuration Guides

Option 1: Expo Ads AdMob Configuration

Step 3: Configure App.json for AdMob

Update your app.json to include AdMob configuration:

{
  "expo": {
    "plugins": [
      [
        "expo-ads-admob",
        {
          "androidAppId": "ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy",
          "iosAppId": "ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"
        }
      ]
    ]
  }
}

Step 4: Create AdMob Component

import React, { useState, useEffect } from 'react';
import { View, Platform } from 'react-native';
import {
  AdMobBanner,
  AdMobInterstitial,
  AdMobRewarded,
  setTestDeviceIDAsync
} from 'expo-ads-admob';

// Define your ad unit IDs
const BANNER_AD_UNIT_ID = Platform.select({
  ios: 'ca-app-pub-xxx/yyy',
  android: 'ca-app-pub-xxx/yyy'
});

const INTERSTITIAL_AD_UNIT_ID = Platform.select({
  ios: 'ca-app-pub-xxx/yyy',
  android: 'ca-app-pub-xxx/yyy'
});

const REWARDED_AD_UNIT_ID = Platform.select({
  ios: 'ca-app-pub-xxx/yyy',
  android: 'ca-app-pub-xxx/yyy'
});

const AdMobManager = ({ style }) => {
  const [isTestMode, setIsTestMode] = useState(true);

  useEffect(() => {
    // Set up test devices during development
    const setupTestDevices = async () => {
      if (isTestMode) {
        await setTestDeviceIDAsync('EMULATOR');
      }
    };

    setupTestDevices();
  }, [isTestMode]);

  // Banner Ad Component
  const BannerAdComponent = () => (
    <AdMobBanner
      bannerSize="smartBannerPortrait"
      adUnitID={BANNER_AD_UNIT_ID}
      servePersonalizedAds={true}
      onAdFailedToLoad={(error) => console.error('Banner Ad Error:', error)}
    />
  );

  // Interstitial Ad Loading and Showing
  const loadInterstitial = async () => {
    try {
      await AdMobInterstitial.setAdUnitID(INTERSTITIAL_AD_UNIT_ID);
      await AdMobInterstitial.requestAdAsync();
      await AdMobInterstitial.showAdAsync();
    } catch (error) {
      console.error('Interstitial Ad Error:', error);
    }
  };

  // Rewarded Ad Loading and Showing
  const loadRewardedAd = async () => {
    try {
      await AdMobRewarded.setAdUnitID(REWARDED_AD_UNIT_ID);
      await AdMobRewarded.requestAdAsync();
      await AdMobRewarded.showAdAsync();
    } catch (error) {
      console.error('Rewarded Ad Error:', error);
    }
  };

  return (
    <View style={[{ alignItems: 'center' }, style]}>
      <BannerAdComponent />
    </View>
  );
};

export default AdMobManager;

Option 2: React Native Google Mobile Ads Configuration

Additional Configuration Steps

iOS (Info.plist)

Add to your ios/YourProject/Info.plist:

GADApplicationIdentifier
ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy

Android (AndroidManifest.xml)

Add to your android/app/src/main/AndroidManifest.xml:

android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>

AdMob Manager Component

import React, { useEffect } from 'react';
import { View, Platform } from 'react-native';
import { 
  MobileAds, 
  BannerAd, 
  BannerAdSize, 
  InterstitialAd, 
  AdEventType,
  TestIds,
  RewardedAd,
  RewardedAdEventType
} from 'react-native-google-mobile-ads';

// Configure Ad Units
const BANNER_AD_UNIT_ID = __DEV__ 
  ? TestIds.BANNER 
  : Platform.select({
      ios: 'ca-app-pub-xxx/yyy',
      android: 'ca-app-pub-xxx/yyy'
    });

const INTERSTITIAL_AD_UNIT_ID = __DEV__ 
  ? TestIds.INTERSTITIAL 
  : Platform.select({
      ios: 'ca-app-pub-xxx/yyy',
      android: 'ca-app-pub-xxx/yyy'
    });

const REWARDED_AD_UNIT_ID = __DEV__ 
  ? TestIds.REWARDED 
  : Platform.select({
      ios: 'ca-app-pub-xxx/yyy',
      android: 'ca-app-pub-xxx/yyy'
    });

const AdMobManager = ({ style }) => {
  useEffect(() => {
    // Initialize MobileAds
    MobileAds()
      .initialize()
      .then(adapterStatuses => {
        // Initialization complete
        console.log('AdMob Initialization complete', adapterStatuses);
      });
  }, []);

  // Banner Ad Component
  const BannerAdComponent = () => (
    <BannerAd
      unitId={BANNER_AD_UNIT_ID}
      size={BannerAdSize.FULL_BANNER}
      requestOptions={{
        requestNonPersonalizedAdsOnly: true,
      }}
      onAdLoaded={() => {
        console.log('Banner ad loaded');
      }}
      onAdFailedToLoad={(error) => {
        console.error('Banner ad failed to load', error);
      }}
    />
  );

  // Interstitial Ad Management
  const loadInterstitial = () => {
    const interstitial = InterstitialAd.createForAdRequest(INTERSTITIAL_AD_UNIT_ID, {
      requestNonPersonalizedAdsOnly: true,
    });

    interstitial.addAdEventListener(AdEventType.LOADED, () => {
      interstitial.show();
    });

    interstitial.addAdEventListener(AdEventType.CLOSED, () => {
      // Ad closed, load a new one
      interstitial.load();
    });

    // Begin loading
    interstitial.load();
  };

  // Rewarded Ad Management
  const loadRewardedAd = () => {
    const rewarded = RewardedAd.createForAdRequest(REWARDED_AD_UNIT_ID, {
      requestNonPersonalizedAdsOnly: true,
    });

    rewarded.addAdEventListener(RewardedAdEventType.LOADED, () => {
      rewarded.show();
    });

    rewarded.addAdEventListener(RewardedAdEventType.EARNED_REWARD, reward => {
      console.log('User earned reward of ', reward);
      // Handle user reward
    });

    // Begin loading
    rewarded.load();
  };

  return (
    <View style={[{ alignItems: 'center' }, style]}>
      <BannerAdComponent />
    </View>
  );
};

export default AdMobManager;

Implementing Ads in Your App

Banner Ads

Simply import and use the AdMobManager component:

import React from 'react';
import { View } from 'react-native';
import AdMobManager from './AdMobManager';

const HomeScreen = () => {
  return (
    <View>
      {/* Your screen content */}
      <AdMobManager style={{ marginTop: 10 }} />
    </View>
  );
};

Interstitial Ads

Trigger at strategic points in your app:

const GameOverScreen = () => {
  const handleGameOver = async () => {
    // Show interstitial ad after game ends
    await loadInterstitial();
  };

  return (
    <View>
      {/* Game over content */}
    </View>
  );
};

Rewarded Ads

Implement in scenarios like extra lives or in-app rewards:

const RewardScreen = () => {
  const handleGetReward = async () => {
    try {
      await loadRewardedAd();
      // Handle reward logic after ad completion
    } catch (error) {
      console.error('Reward Ad Error:', error);
    }
  };

  return (
    <View>
      {/* Reward screen content */}
    </View>
  );
};

Performance Optimization

  • Load ads before displaying
  • Handle ad loading errors gracefully
  • Don't overload your app with too many ads
  • Respect user experience

Recommended Additional Packages

  • @react-native-async-storage/async-storage: For storing ad preferences
  • react-native-device-info: For more precise device targeting

Consent and Privacy

Implement user consent mechanisms:

import { MobileAds } from 'react-native-google-mobile-ads';

// Request consent if required (GDPR compliance)
MobileAds()
  .requestConsent({
    // Configuration options for consent
    debugGeography: DebugGeography.EEA,
  })
  .then(consentInfo => {
    // Handle consent
  });

Troubleshooting

  • Verify ad unit IDs are correct
  • Check network connectivity
  • Use console logs for debugging
  • Ensure proper SDK initialization

Conclusion

Integrating AdMob requires careful implementation. Follow Google's guidelines, respect user experience, and continuously test your implementation.

Final Code Structure

your-expo-project/
│
├── components/
│   └── AdMobManager.js
│
├── screens/
│   ├── HomeScreen.js
│   ├── GameOverScreen.js
│   └── RewardScreen.js
│
└── app.json

Happy monetizing! 💰📱


I hope this guide helps you successfully integrate AdMob into your React Native Expo app! Feel free to leave questions in the comments below.