How to monetize your mobile app: AdMob + Firebase

You can easily monetize your Android app with AdMob ads, and here I’ll show you how to add most popular ad types with Firebase analytics integrated.

I’d already wrote a post about AdMob ads, but the service keeps changing, and this is why I decided to make new tutorial on this topic.

Right after creating a new Android project, you need to add packages required for AdMob ads. Now all of this is in com.google.firebase:firebase-ads package, so we need to add the following line to app’s build.gradle file (./app/build.gradle):

implementation 'com.google.firebase:firebase-ads:17.1.2'

So, let’s see how we can add such AdMob ads as banner, interstitial, or rewarded video ad. As a UI, we will just put two buttons on the main screen, and place a banner at the bottom.

Banner

Here’s how activity_main.xml should look like:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="center">

        <Button
                android:id="@+id/btn_interstitial"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:onClick="onShowInterstitial"
                android:text="Interstitial"/>

        <Button
                android:id="@+id/btn_video"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:onClick="onShowRewardedVideo"
                android:text="Rewarded Video"/>

    </LinearLayout>

    <com.google.android.gms.ads.AdView
            android:id="@+id/banner_ad"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            ads:adSize="BANNER"
            ads:adUnitId="@string/banner_id">
    </com.google.android.gms.ads.AdView>

</FrameLayout>

Here we just put 2 buttons at the center of the screen, and this code snippet is for the bottom banner:

<com.google.android.gms.ads.AdView
        android:id="@+id/banner_ad"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        ads:adSize="SMART_BANNER"
        ads:adUnitId="@string/banner_id">
</com.google.android.gms.ads.AdView>

adSize argument is set to SMART_BANNER here, so that banner height would fit automatically depending on screen’s size. Here is the table for this dependency:

Ad heightScreen height
32 dp≤ 400 dp
50 dp> 400 dp and ≤ 720 dp
90 dp> 720 dp

And here are all possible banner’s sizes:

Size in dp (WxH)DescriptionAvailabilityAdSize constant
320×50BannerPhones and TabletsBANNER
320×100Large BannerPhones and TabletsLARGE_BANNER
300×250IAB Medium RectanglePhones and TabletsMEDIUM_RECTANGLE
468×60IAB Full-Size BannerTabletsFULL_BANNER
728×90IAB LeaderboardTabletsLEADERBOARD
Screen width x 32|50|90Smart BannerPhones and TabletsSMART_BANNER

Set adUnitId argument to banner’s Ad Unit ID which you created in AdMob console. Here in this project we keep all ads id in /res/values/ads.xml file:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_id">ca-app-pub-3940256099942544~3347511713</string>
    <string name="banner_id">ca-app-pub-3940256099942544/6300978111</string>
</resources>

These ids (and all ids below) are from Google’s test ad units, which you can freely use for development and testing.

We’ve got only 2 ids for now – one for app and one for the bottom banner.

Now let’s check if this banner works at all – add following lines to the MainActivity class. First, let’s initialize ad SDK in onCreate():

MobileAds.initialize(this, getString(R.string.app_id))

And setup banner loading:

val adView = findViewById<AdView>(R.id.banner_ad)
adView.loadAd(getAdRequest())

getAdRequest() is a utility private function – since we will create AdRequest frequently, I moved this process to a separate method:

private fun getAdRequest(): AdRequest {
    return AdRequest.Builder().build()
}

Don’t forget to change the manifest accordingly. This line is for <application/> tag:

<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="@string/app_id"/>

And this one is for root <manifest/> tag:

<uses-permission android:name="android.permission.INTERNET"/>

Now let’s run the app and see what we have:

admob+firebase: banner

Yay, first ad is ready to go!

Interstitial

Now let’s go to fullscreen ad. Interstitial ad should be opened after click on btn_interstitial, but for user’s convenience we’ll start loading ad content in onCreate() and update it after each ad show.

First, we declare a variable in MainActivity:

private lateinit var mInterstitialAd: InterstitialAd

lateinit is used here, because we initialize mInterstitialAd in onCreate() and it must not be null. We also load ad content for the first time in onCreate():

mInterstitialAd = InterstitialAd(this)
mInterstitialAd.adUnitId = getString(R.string.interstitial_id)
mInterstitialAd.loadAd(getAdRequest())

Ad Unit ID is set to interstitial_id string value from values/ads.xml:

<string name="interstitial_id">ca-app-pub-3940256099942544/1033173712</string>

Now it’s time to create onShowInterstitial() method which is responsible for btn_interstitial onClick callback (it was set via xml file):

public fun onShowInterstitial(view: View) {
   if(mInterstitialAd.isLoaded) {
       mInterstitialAd.show()
    }
}

Here we must check if the ad was loaded or not before showing it.

Time to run the app and check our interstitial ad. Here’s how it should look like:

admob+firebase: interstitial

So, we can now add a listener which will be responsible for displaying an error message (if ad failed to load) and for updating ad request after ad was closed.

Let’s create Ad Listener instance in MainActivity class:

private val mInterstitialAdListener = object : AdListener() {

    override fun onAdFailedToLoad(errorCode: Int) {
        Toast.makeText(
            this@MainActivity,
            "Interstitial ad failed to load: ${Utils.getUserFriendlyError(errorCode)}",
            Toast.LENGTH_LONG)
            .show()
    }

    override fun onAdClosed() {
        mInterstitialAd.loadAd(getAdRequest())
    }
}

And link to our interstitial ad in onCreate():

mInterstitialAd.adListener = mInterstitialAdListener

To check if the ad is really updated each time it’s shown to a user, we need to change test ad unit id (from Google) to your own in ads.xml. Google’s test ads always show the same picture, so we won’t be able to say if it was updated or not. This is what it should look like:

Rewarded Video Ad

Now we can create the last type of ad – rewarded video.

Let’s first create a variable for rewarded video ad in MainActivity:

private lateinit var mRewardedVideoAd: RewardedVideoAd

Initialize it in onCreate() and request first ad content:

mRewardedVideoAd = MobileAds.getRewardedVideoAdInstance(this)
mRewardedVideoAd.loadAd(getString(R.string.rewarded_video_id), getAdRequest())

It is very important to use Activity instead of Application as an argument in MobileAds.getRewardedVideoAdInstance() method. If you plan to enable ad mediation, be aware that some mediation adapters requires Activity instance only.

Here is how onShowRewardedVideo() should look like (same logic as in onShowInterstitial()) and it’s called on ‘Rewarded Video’ button click.

public fun onShowRewardedVideo(view: View) {
    if(mRewardedVideoAd.isLoaded) mRewardedVideoAd.show()
}

We also need to create the following listener in MainActivity to handle all important events in rewarded video lifecycle:

private val mRewardedVideoAdListener = object : RewardedVideoAdListener {

    override fun onRewardedVideoAdLeftApplication() { }

    override fun onRewardedVideoAdLoaded() { }

    override fun onRewardedVideoAdOpened() { }

    override fun onRewardedVideoCompleted() { }

    override fun onRewardedVideoStarted() { }

    override fun onRewardedVideoAdClosed() {
        mRewardedVideoAd.loadAd(getString(R.string.rewarded_video_id), getAdRequest())
    }

    override fun onRewarded(reward: RewardItem?) {
        Toast.makeText(this@MainActivity, "Here is your reward!", Toast.LENGTH_SHORT).show()
    }

    override fun onRewardedVideoAdFailedToLoad(errorCode: Int) {
        Toast.makeText(
            this@MainActivity,
            "Rewarded video ad failed to load: ${Utils.getUserFriendlyError(errorCode)}",
            Toast.LENGTH_LONG)
            .show()
    }

}

Here we only need to override 3 methods: onRewarded(), nRewardedVideoAdClosed() and onRewardedVideoAdFailedToLoad(). onRewarded() method is the best place to give our user a reward (sic!) for watching our video ad. In this app we just showing a toast message with confirmation. All other mentioned methods are made with the same logic as in interstitial ad.

Now we link this listener with rewarded video object in onCreate():

mRewardedVideoAd.rewardedVideoAdListener = mRewardedVideoAdListener

Run the app, check the ad. You should see the following after clicking on ‘Rewarded Video’ button:

admob+firebase: rewarded video

Firebase integration

Now few words about creating a Firebase project for our app and linking AdMob analytics.

As a first step – you should go to Firebase console and select ‘Add Project’:

Here you need to enter the package name and tap on ‘Create project’. Project can contain multiple apps, so you may, for example, group all your test apps into one project.

So, project is created and now you’re on it’s Home page. Tap on Android icon to add android app to the project:

There will be a window with 4-step process:

As a first step, enter only package name (be careful!) and click on ‘Register app’. After that, download google-services.json to /app project directory. Follow the instructions to add required packages for Firebase core features (don’t mess up build.gradle files) and you can run your app to test it out.

Now move to ‘AdMob’ tab and click on ‘Link’. It should take you to AdMob website to ‘Apps’ tab where we click on ‘Link to Firebase’ for selected app. Then enter package name, select existing Firebase project and AdMob will automatically find our app.

You will see first ad stats in a few hours.

App’s source code you can find here: https://github.com/nerdgrlapps/admobtutorial

Apk as a ready-to-use demonstration.

Leave a Reply

Your email address will not be published. Required fields are marked *