In many applications that we build we want to offer some way to monetize the product. Be it through in-app purchases, subscriptions or even advertisements – these all provide a way for developers to monetize their application. We’ve long experienced, or implemented, ads through our Android and iOS applications, and now that we’re building Flutter apps we want to be able to do the same here too. In this article we’re going to explore the in-app advertisement capabilities when it comes to Flutter and learn how to implement these within our own apps.
Companion video for this post
It’s important to note that there are a couple of different packages available for admob when it comes to flutter. There is the admob_flutter package, followed by the firebase_admob package. For this post i’ve decided to take a look at the first option, admob_flutter. First of all I’ve been using this in my own recent side-project and I much prefer the API for this package, both in the way to operate and understand. It’s definitely worth checking out the latter though to see what works best for you 🙂 Regardless of what solution you go for when implementing ads, this article will help to explore the concepts and different components involved – as all things such as ad types and events remain the same throughout the different flutter packages available.
We’re going to begin by adding the in-app purchase package to our list of dependencies in our pub.yaml file:
admob_flutter: ^0.3.1
Before we can add any advertisements to our application, we need to configure our application with our admob account id. If you don’t have an admob account yet (or even any ads setup within your account), admob provides us with a test ID that we can use within our projects.
ca-app-pub-3940256099942544~3347511713
Note: For the adverts used in this post we’re making use of the test ad IDs provided by google here.
Whether we’re using our own or the test ID, we need to add this ID to the Android and/or iOS parts of our flutter project. For Android we need to add this to the manifest as meta-data against the gms.ads.APPLICATION_ID name. This means that
<manifest> <application> <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-3940256099942544~3347511713"/> </application> </manifest>
For iOS we need to add the same ID within our Info.plist file against the GADApplicationIdentifier key. You’ll also need to opt-in for the embedded_views_preview as stated in the code below.
<key>GADApplicationIdentifier</key> <string>ca-app-pub-3940256099942544~1458002511</string> <key>io.flutter.embedded_views_preview</key> <true/>
import 'package:admob_flutter/admob_flutter.dart'; void main() { Admob.initialize("your_app_id"); ... }
Now we’ve got the package added to our project and our configuration setup, we can begin diving into getting some ads into our applications. When it comes to these ads, the package currently supports three different types of ads that can be embedded – banner, interstitial and reward.
Each of these advertisement approaches provides us with a way to monetize via advertisements within our application. Let’s begin by taking a look at implementing banner ads and how they can be configured to suit our needs.
Admob Banner
The AdMob Banner component allows us to display a banner style advertisement within our application. The package is using native platform views to render these advertisements, allowing us to place them amongst the other widgets within our user interface. When it comes to the AdMob banner, there is a lot that ties everything together – let’s take a quick look at what this widget is made up of:
We start here with the AdMobBanner widget, this is the component used to place a banner within our layout to the user. The banner will display an ad, at the specified size, and when clicked will take the user to the ad destination. This widget can be placed directly into our widget tree:
AdmobBanner(adUnitId: "ca-app-pub-3940256099942544/6300978111", adSize: AdmobBannerSize.LARGE_BANNER)
When we construct this widget we can pass in a collection of different arguments:
adUnitId – the ID for the advertisement that we want to display
adSize – This is the size of the ad and must be in the form of an AdmobBannerSize value, which can be one of:
- BANNER – A banner sized 320 x 50
- LARGE_BANNER – A banner sized 320 x 100
- MEDIUM_RECTANGLE – A banner sized 320 x 250
- FULL_BANNER – A banner sized 468 x 60
- LEADERBOARD – A banner sized 728 x 90
- SMART_BANNER – A banner that can be placed inside of a container of any size
listener – This is a listener which can be provided to listen for events that occur around the AdmobBanner. The callback for the listener provides us with an instance of an AdmobAdEvent, along with any data for the event in the form of a Map
listener: (AdmobAdEvent event, Map<String, dynamic> args) { switch (event) { ... } }
When it comes to the AdmobAdEvent type, this can be one of the following:
- loaded – the advert has been loaded into view successfully
- opened – the advert was opened and the user moved from the content of the app
- closed – the advert was closed and the user returned to the app
- failedToLoad – the advert has failed to load into the banner view
- clicked – the advert has been clicked by the user
- impression – a new advert was shown / the ad was refreshed whilst the user was looking at the ad
- leftApplication – the application has been exited after clicking an ad
- completed – for the video ads this is used when the the ad has completed playing
- rewarded – the ad has sent a reward amount
- started – for the video ads this is used when the the ad has started to play
As you can see from above, there are quite a few events which can be received by the listener. However, not all of these will apply to all ad types that are being used in your application. For example, if you aren’t using reward or full-screen adverts then several of these can be removed for use.
When it comes to the args Map that can be received, this is currently only made use of by two of the events. First of all when failedToLoad occurs an errorCode will be sent with the data map, secondly for the rewarded event – here we will receive an amount argument which corresponds to the rewarded amount for the advert.
onBannerCreated – this is a listener which can be set to listen for when the banner ad widget has been successfully created. This may be useful for knowing when to show or hide a certain piece of the UI. For example, maybe you don’t want to show app content until the app has loaded, or you want to show some form of progress in place in the meantime.
onBannerCreated: (AdmobBannerController controller) { ... }
Interstitial Ad
The next type of ad that we can use in our application is the interstitial ad – this is a full screen ad that is displayed to the user, rather than within the layout of a screen in your application. When it comes to the AdmobInterstitial class, there is a lot that ties everything together – let’s take a quick look at what this widget is made up of:
As you can see here, there isn’t so much that makes up this class when compared with the AdMobBanner. Because of this ad being launched full screen, there is no need to render a Platform View (like the AdMobBanner), so there is a lot of the complexity removed for this ad type. We’ll start at the top of the diagram with the AdmobInterstitial class which is used to instantiate this ad type:
AdmobInterstitial interstitialAd = AdmobInterstitial( adUnitId: "some_add_unit_id", );
For the AdmobInterstitial instance we can pass in only an adUnitId and a listener – both of these arguments are the same as when using the AdmobBanner class.
When it comes to this type of Ad though, there are a couple of differences. The main one is how I previously mentioned that the interstitial ad is not within the existing layout of our screen – instead it is launched full screen to the user. Because of this nature of the ad we need to first ensure that the instance of our ad has been full loaded before we can display it to the user. For this we need to make use of the provided load() method to load up the content of the advert ready for display:
interstitialAd.load();
When we call this, the package will begin asynchronously loading our advert using the provided adUnitId – our listener will also be set if we have provided one for use. If so, we will receive state events through our listener on the state of the advert (for example, once it has loaded successfully or failed to load).
Because we don’t want to show this ad to the user until it has fully loaded, we do need to observe the state of the advert. Whilst we could use the provided listener to do so, the AdmobInterstitial class provides us with an isLoaded property that provides us with a Future<bool> to observe for when the advert has been loaded successfully. Once we are aware that the ad has been loaded we can go ahead and invoke the show() function to display this ad to our users.
if (await interstitialAd.isLoaded) { interstitialAd.show(); }
Finally, once we are finished with the advert we must invoke the dispose() function to perform the required clean-up for the ad resources.
interstitialAd.dispose();
Reward advert
Finally we have the reward advert – this can be used in cases where we wish to reward the user in some way for watching an advert shown on screen. For example, in a game we may give the users in-app currency once they have watched an advert, or let them proceed to a piece of content in the app once the advert has been watched. In either case we can make use of the AdmobReward class to implement this functionality within our app.
As you can see from the above, the structure for the AdMobReward is pretty much the same as the AdMobInterstitial class. We pass in exactly the same required agruments and also need to handle the lifecycle of the advert in exactly the same way
We begin by creating a new instance of the AdmobReward class:
AdmobReward admobReward = AdmobReward( adUnitId: "some_add_unit_id", );
We then need to load, show ad dispose of the advert in the same way that we did for the AdMobInterstitial class.
admobReward.load(); if (await admobReward.isLoaded) { admobReward.show(); } admobReward.dispose();
One difference with the AdmobReward class is the listener – whilst the listener itself is the same, there is an extra event which we can listen for events from. This AdmobAdEvent.rewarded type allows us to receive when the user is rewarded for watching the advert, providing us with the type of reward along with the amount for it also. This event will be triggered once the user has finished watching the advert and been awarded with the reward for doing so – if the user does not complete the advert then the amount will not be rewarded to them.
AdmobReward( adUnitId: "some_ad_unit_id", listener: (AdmobAdEvent event, Map<String, dynamic> args) { if (event == AdmobAdEvent.rewarded) { print('User was rewarded!'); print('Reward type: ${args['type']}'); print('Reward amount: ${args['amount']}'); } }, );
With all of the above in mind, we’ve covered how to implement three different types of advertisements into our flutter applications. We can now show banner adverts of varying sizes, display interstitial adverts to the user and always reward users for viewing specific adverts that we display. When implemented sensibly, these adverts can allow developers to bring in revenue from adverts in their applications whilst still keeping users engaged with their applications – helping to keep app development sustainable for products that may have a free users or a free plan in place.
From this article we can see that adding these adverts to our applications does not require many steps at all. Once we’ve configured the package with our ad account it’s a case of dropping in the widgets where we see fit. I’m looking forward to seeing / hearing how this process works for your applications – please feel free to reach out should you have any thoughts or questions that you’d like to share!