Adding Google AdMob to Expo Apps (2025)

Josie Daw

Posted on • Edited on

Adding Google AdMob to Expo Apps (3) Adding Google AdMob to Expo Apps (4) Adding Google AdMob to Expo Apps (5) Adding Google AdMob to Expo Apps (6) Adding Google AdMob to Expo Apps (7)

#expo #admob #monetization #reactnative

Table of Contents

1. Getting Started
2. Using Expo Development Builds
3. Preparing AdMob
4. Using React Native Google Mobile Ads
5. Creating a Banner Ad
6. Creating an Interstitial Ad
7. Configure Ads for Production
8. Common Problems with Google Admob for Expo/React Native

Getting Started

This post is a brief guide on adding banner ads and interstitial ads to a simple Expo project using Google AdMob and React Native Google Mobile Ads.

  1. Create your Expo project.
  2. Create a Google AdMob account and make sure to complete the verification process.

Using Expo Development Builds

Since we will later install React Native Google Mobile Ads, we will not be able to use the Expo Go app to test. As a result, we will need to use the Expo development builds to test our app.

You can follow this tutorial from Expo to setup a development build.

Add the following lines to your package.json (after following the tutorial steps) so that you can easily build development models from your command line.

 "scripts": { ... "dev:build:ios": "eas build --profile development --platform ios", "dev:build:android": "eas build --profile development --platform android", },

Preparing AdMob

Since React Native is a cross-platform framework, you will need to create an app for both iOS and Android. You will need to have apps already published on the App and Play stores to register them with AdMob. If you are following this guide before registering your app on any stores, make sure to just use the test IDs.

After creating the apps in Google AdMob, select the app and then select 'App Settings'. Get the App ID for both Android and iOS. The format of the App ID is always ca-app-pub-12345678910~123456459.

In your app.json/app.config.js, outside of "expo", add a new object with the following structure:

{ "expo": ... "react-native-google-mobile-ads": { "android_app_id": "ca-app-pub-12345678910~123456459", "ios_app_id": "ca-app-pub-12345678910~123456459", }}

You will also need to register your test devices if you are not using emulators. You can follow this guide to register your devices with AdMob.

Don't Forget to Follow Advertising Regulations

Many countries around the world now have explicit consent requirements to display any ads at all. Luckily, Google AdMob and React Native Google Mobile Ads make this easy to do. From the Google AdMob dashboard:

  1. Click Privacy & Messaging
  2. Create messaging for European Regulations, US State Regulations, and any other options.
  3. Click "Publish" for each message.

Using React Native Google Mobile Ads

Start by installing React Native Google Mobile Ads with npm install react-native-google-mobile-ads

If you need to use static frameworks, you should follow an additional step and add this to your plugins in app.json/app.config.js:

 "plugins": [ [ "expo-build-properties", { "ios": { "useFrameworks": "static" } } ] ]

Next, we need to initialize the ads when the app first loads, so on your App.js or your root _layout.jsx/_layout.tsx, add the following code:

import mobileAds from 'react-native-google-mobile-ads';// Go inside your component/function// Initialize Google Mobile Ads SDKuseEffect(() => { (async () => { // Google AdMob will show any messages here that you just set up on the AdMob Privacy & Messaging page const { status: trackingStatus } = await requestTrackingPermissionsAsync(); if (trackingStatus !== 'granted') { // Do something here such as turn off Sentry tracking, store in context/redux to allow for personalized ads, etc. } // Initialize the ads await mobileAds().initialize(); })();}, [])

We are now ready to create our first ad!

Creating a Banner Ad

Banner ads are one of the easiest ways to insert ads into your app without severely interrupting the user experience. You can easily insert them at natural breakpoints in your Views/components.

To insert a banner ad into your app, you must first create one on Google AdMob. For both iOS and Android, go to each App -> Ad Units -> Add Ad Unit -> Select Banner Ad.

You can give the ad any name and adjust the advanced settings to your preferences.

You will be using the Ad ID for the next stage. The Ad ID is different from the App ID. The Ad ID always has a structure of ca-app-pub-12345678910/12345678910. An easy way to tell the difference is that the App ID has a ~ and the Ad ID has a /.

First, install Expo device to be able to display the correct banners: npx expo install expo-device.

Next, let's create a special component to hold our banner ad so that we can easily reuse it anywhere in our app.

Create a new file called InlineAd.tsx (or InlineAd.jsx) and use something like the below code.

By using isAdLoaded and the View style, we can minimize the amount of blank space showing on the app when an ad has not loaded.

Remember, you should put your Ad IDs in environmental variables. The fake IDs below are for display purposes only.

// InlineAd.tsximport { View } from 'react-native';import * as Device from 'expo-device';import React, { useState } from 'react';import { BannerAd, BannerAdSize, TestIds } from 'react-native-google-mobile-ads';const iosAdmobBanner = "ca-app-pub-12345678910/12345678910";const androidAdmobBanner = "ca-app-pub-12345678910/12345678910";const productionID = Device.osName === 'Android' ? androidAdmobBanner : iosAdmobBanner;const InlineAd = () => { const [isAdLoaded, setIsAdLoaded] = useState<boolean>(false); return ( <View style={{ height: isAdLoaded ? 'auto' : 0 }}> <BannerAd // It is extremely important to use test IDs as you can be banned/restricted by Google AdMob for inappropriately using real ad banners during testing unitId={__DEV__ ? TestIds.BANNER : productionID} size={BannerAdSize.ANCHORED_ADAPTIVE_BANNER} requestOptions={{ requestNonPersonalizedAdsOnly: true, // You can change this setting depending on whether you want to use the permissions tracking we set up in the initializing }} onAdLoaded={() => { setIsAdLoaded(true); }} /> </View > );};export default InlineAd;

Now you can insert InlineAd anywhere in your app <InlineAd />.

Here's how it looks!

Creating an Interstitial Ad

Interstitial ads are adverts that take up the entire screen and should be used sparingly as they can dissuade users from using your app if they are overused.

As with the banner ads above, you need to create an interstitial ad for each app and then get the Ad ID in the following format ca-app-pub-12345678910/12345678910.

One of the best way to use interstitial ads is with pagination (i.e.) moving from one page to another.

Below, I will update an existing pagination function to show interstitial ads whenever the user moves to the next page or the previous page.

First, create your Pagination.tsx or Pagination.jsx file. Then, prepare your interstitial Ad IDs. Next, prepare an ad request with keywords or personalized ads.

Then, inside the component itself, use useEffect to load/unload the actual interstitial ad.

The code below prepares the interstitial ad and only shows it (using interstitial.show();) if an ad is loaded and the button is clicked. Sometimes there are no ads available, or the user is offline, so we don't want to cause an accidental error.

We also use the unsubscribeClosed to set the loaded state to false after the interstitial ad has been closed and reload a new ad. This means that no matter how many times a user clicks Previous or Next, there will always be a new ad for them.

Remember, you should put your Ad IDs in environmental variables. The fake IDs below are for display purposes only.

// Pagination.tsximport { AntDesign } from '@expo/vector-icons';import * as Device from 'expo-device';import { Link } from 'expo-router';import React, { useEffect, useState } from 'react';import { View, Button, Text } from 'react-native';import { AdEventType, InterstitialAd, TestIds } from 'react-native-google-mobile-ads';const iosAdmobInterstitial = "ca-app-pub-12345678910/12345678910";const androidAdmobInterstitial = "ca-app-pub-12345678910/12345678910";const productionID = Device.osName === 'Android' ? androidAdmobInterstitial : iosAdmobInterstitial;const adUnitId = __DEV__ ? TestIds.INTERSTITIAL : productionID;// Make sure to always use a test ID when not in production const interstitial = InterstitialAd.createForAdRequest(adUnitId, { keywords: ['food', 'cooking', 'fruit'], // Update based on the most relevant keywords for your app/users, these are just random examples requestNonPersonalizedAdsOnly: true, // Update based on the initial tracking settings from initialization earlier});const Pagination = ({ }) => { const [loaded, setLoaded] = useState<boolean>(false); useEffect(() => { // Event listener for when the ad is loaded const unsubscribeLoaded = interstitial.addAdEventListener(AdEventType.LOADED, () => { setLoaded(true); }); // Event listener for when the ad is closed const unsubscribeClosed = interstitial.addAdEventListener(AdEventType.CLOSED, () => { setLoaded(false); // Load a new ad when the current ad is closed interstitial.load(); }); // Start loading the interstitial ad straight away interstitial.load(); // Unsubscribe from events on unmount return () => { unsubscribeLoaded(); unsubscribeClosed(); }; }, []); return ( <View style={{ width: '100%', flexDirection: 'row', justifyContent: 'space-evenly', alignItems: 'center', marginVertical: 8, paddingHorizontal: 10, }}> <Link asChild href="/previous-page"> <Button onPress={() => { if (loaded) { interstitial.show(); } }}> <> <AntDesign name="arrowleft" size={24} color="#fdb833" /> <Text> Previous </Text> </> </Button> </Link> <Link asChild href="/next-page"> <Button onPress={() => { if (loaded) { interstitial.show(); } }}> <> <Text> Next </Text> <AntDesign name="arrowright" size={24} color="#fdb833" /> </> </Button> </Link> </View> );};export default Pagination;

Now you will have functioning interstitial ads on your app!

Here's how it will look:

After following the steps above, you should be able to see test ads in your app. However, if you want to show ads on a production level app, you need to take some additional steps.

Configure Ads for Production

In your app.json/app.config.js add the below to the react-native-google-mobile-ads section.

user_tracking_usage_description will display to users to provide informed consent.
sk_ad_network_items includes all of the SKAdNetwork names to make sure that all of the ad impressions and conversions are tracked for your app.

{ "react-native-google-mobile-ads": { "android_app_id": "ca-app-pub-12345678910~123456459", "ios_app_id": "ca-app-pub-12345678910~123456459", "delay_app_measurement_init": true, "user_tracking_usage_description": "This identifier will be used to deliver personalized ads to you.", "sk_ad_network_items": [ "cstr6suwn9.skadnetwork", "4fzdc2evr5.skadnetwork", "4pfyvq9l8r.skadnetwork", "2fnua5tdw4.skadnetwork", "ydx93a7ass.skadnetwork", "5a6flpkh64.skadnetwork", "p78axxw29g.skadnetwork", "v72qych5uu.skadnetwork", "ludvb6z3bs.skadnetwork", "cp8zw746q7.skadnetwork", "c6k4g5qg8m.skadnetwork", "s39g8k73mm.skadnetwork", "3qy4746246.skadnetwork", "3sh42y64q3.skadnetwork", "f38h382jlk.skadnetwork", "hs6bdukanm.skadnetwork", "v4nxqhlyqp.skadnetwork", "wzmmz9fp6w.skadnetwork", "yclnxrl5pm.skadnetwork", "t38b2kh725.skadnetwork", "7ug5zh24hu.skadnetwork", "9rd848q2bz.skadnetwork", "y5ghdn5j9k.skadnetwork", "n6fk4nfna4.skadnetwork", "v9wttpbfk9.skadnetwork", "n38lu8286q.skadnetwork", "47vhws6wlr.skadnetwork", "kbd757ywx3.skadnetwork", "9t245vhmpl.skadnetwork", "a2p9lx4jpn.skadnetwork", "22mmun2rn5.skadnetwork", "4468km3ulz.skadnetwork", "2u9pt9hc89.skadnetwork", "8s468mfl3y.skadnetwork", "av6w8kgt66.skadnetwork", "klf5c3l5u5.skadnetwork", "ppxm28t8ap.skadnetwork", "424m5254lk.skadnetwork", "ecpz2srf59.skadnetwork", "uw77j35x4d.skadnetwork", "mlmmfzh3r3.skadnetwork", "578prtvx9j.skadnetwork", "4dzt52r2t5.skadnetwork", "gta9lk7p23.skadnetwork", "e5fvkxwrpn.skadnetwork", "8c4e2ghe7u.skadnetwork", "zq492l623r.skadnetwork", "3rd42ekr43.skadnetwork", "3qcr597p9d.skadnetwork", "vutu7akeur.skadnetwork", "eh6m2bh4zr.skadnetwork", "pwa73g5rt2.skadnetwork" ] }}

In the "expo" section of your app.json/app.config.js, you also need to add the following to your "android" and "ios" sections.

"android": { "versionCode": 1, "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#FFFFF" }, "package": "com.fakeapp.name", "permissions": ["com.google.android.gms.permission.AD_ID"], "googleServicesFile": "./google-services.json"}, "ios": { "buildNumber": "1", "supportsTablet": true, "infoPlist": { "NSUserTrackingUsageDescription": "Allow this app to collect app-related data that can be used for tracking you or your device and deliver personalized ads to you.", "SKAdNetworkItems": [ { "SKAdNetworkIdentifier": [ "cstr6suwn9.skadnetwork", "4fzdc2evr5.skadnetwork", "4pfyvq9l8r.skadnetwork", "2fnua5tdw4.skadnetwork", "ydx93a7ass.skadnetwork", "5a6flpkh64.skadnetwork", "p78axxw29g.skadnetwork", "v72qych5uu.skadnetwork", "ludvb6z3bs.skadnetwork", "cp8zw746q7.skadnetwork", "c6k4g5qg8m.skadnetwork", "s39g8k73mm.skadnetwork", "3qy4746246.skadnetwork", "3sh42y64q3.skadnetwork", "f38h382jlk.skadnetwork", "hs6bdukanm.skadnetwork", "v4nxqhlyqp.skadnetwork", "wzmmz9fp6w.skadnetwork", "yclnxrl5pm.skadnetwork", "t38b2kh725.skadnetwork", "7ug5zh24hu.skadnetwork", "9rd848q2bz.skadnetwork", "y5ghdn5j9k.skadnetwork", "n6fk4nfna4.skadnetwork", "v9wttpbfk9.skadnetwork", "n38lu8286q.skadnetwork", "47vhws6wlr.skadnetwork", "kbd757ywx3.skadnetwork", "9t245vhmpl.skadnetwork", "a2p9lx4jpn.skadnetwork", "22mmun2rn5.skadnetwork", "4468km3ulz.skadnetwork", "2u9pt9hc89.skadnetwork", "8s468mfl3y.skadnetwork", "av6w8kgt66.skadnetwork", "klf5c3l5u5.skadnetwork", "ppxm28t8ap.skadnetwork", "424m5254lk.skadnetwork", "ecpz2srf59.skadnetwork", "uw77j35x4d.skadnetwork", "mlmmfzh3r3.skadnetwork", "578prtvx9j.skadnetwork", "4dzt52r2t5.skadnetwork", "gta9lk7p23.skadnetwork", "e5fvkxwrpn.skadnetwork", "8c4e2ghe7u.skadnetwork", "zq492l623r.skadnetwork", "3rd42ekr43.skadnetwork", "3qcr597p9d.skadnetwork", "vutu7akeur.skadnetwork", "eh6m2bh4zr.skadnetwork", "pwa73g5rt2.skadnetwork" ] } ] }, "bundleIdentifier": "com.fakeapp" }

You also need to all the following plugins for transparency:

"expo": { ... plugins: [ [ 'expo-tracking-transparency', { userTrackingPermission: 'Allow this app to collect app-related data that can be used for tracking you or your device and deliver personalized ads to you.', }, ], [ 'expo-build-properties', { ios: { useFrameworks: 'static', }, android: { extraProguardRules: '-keep class com.google.android.gms.internal.consent_sdk.** { *; }', }, }, ], ], }

Common Problems with Google AdMob for Expo/React Native

1. My ads are showing during testing but not in production

Usually this means that your App IDs or your Ad IDs are configured incorrectly. Make sure that you have added the correct ones.

Note: if you are using environmental variables with Expo eas build, you need to include the variables in the eas.json and also submit the secrets on the Expo website.

2. My ads are showing perfectly but I am not getting any impressions on the AdMob dashboard

Sometimes it take can take a few days for new apps to start registering ads correctly on the dashboard. Make sure that all of your configurations and verifications on the AdMob dashboard are completed properly.

3. My ads are only showing impressions for one of my apps on the AdMob dashboard

This problem is usually caused by accidentally using the same Ad ID for both iOS and Android. Double check that each device type is using its own Ad ID. (i.e. Device.osName === 'Android' ? androidAdmobInterstitialId : iosAdmobInterstitialId; )

Thanks for following along with this tutorial for adding Google AdMob to Expo devices! If you're interested in learning more about me, you can visit my portfolio here.

If you are facing an error anywhere along the way that is not one of the common problems I've already answered, feel free to leave a comment below and we can try to debug it together!

Adding Google AdMob to Expo Apps (2025)
Top Articles
Latest Posts
Recommended Articles
Article information

Author: Rev. Porsche Oberbrunner

Last Updated:

Views: 5944

Rating: 4.2 / 5 (53 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Rev. Porsche Oberbrunner

Birthday: 1994-06-25

Address: Suite 153 582 Lubowitz Walks, Port Alfredoborough, IN 72879-2838

Phone: +128413562823324

Job: IT Strategist

Hobby: Video gaming, Basketball, Web surfing, Book restoration, Jogging, Shooting, Fishing

Introduction: My name is Rev. Porsche Oberbrunner, I am a zany, graceful, talented, witty, determined, shiny, enchanting person who loves writing and wants to share my knowledge and understanding with you.