# firebase_admob

A plugin for [Flutter](https://flutter.io) that supports loading and
displaying banner, interstitial (full-screen), and rewarded video ads using the
[Firebase AdMob API](https://firebase.google.com/docs/admob/).

*Note*: This plugin is in beta, and may still have a few issues and missing APIs.
[Feedback](https://github.com/flutter/flutter/issues) and
[Pull Requests](https://github.com/flutter/plugins/pulls) are welcome.

## Initializing the plugin
The AdMob plugin must be initialized with an AdMob App ID.

```
FirebaseAdMob.instance.initialize(appId: appId);
```

## Using banners and interstitials
Banner and interstitial ads can be configured with target information. 
And in the example below, the ads are given test ad unit IDs for a quick start.

```
MobileAdTargetingInfo targetingInfo = new MobileAdTargetingInfo(
  keywords: <String>['flutterio', 'beautiful apps'],
  contentUrl: 'https://flutter.io',
  birthday: new DateTime.now(),
  childDirected: false,
  designedForFamilies: false,
  gender: MobileAdGender.male, // or MobileAdGender.female, MobileAdGender.unknown
  testDevices: <String>[], // Android emulators are considered test devices
);

BannerAd myBanner = new BannerAd(
  // Replace the testAdUnitId with an ad unit id from the AdMob dash.
  // https://developers.google.com/admob/android/test-ads
  // https://developers.google.com/admob/ios/test-ads
  adUnitId: BannerAd.testAdUnitId,
  size: AdSize.smartBanner,
  targetingInfo: targetingInfo,
  listener: (MobileAdEvent event) {
    print("BannerAd event is $event");
  },
);

InterstitialAd myInterstitial = new InterstitialAd(
  // Replace the testAdUnitId with an ad unit id from the AdMob dash.
  // https://developers.google.com/admob/android/test-ads
  // https://developers.google.com/admob/ios/test-ads
  adUnitId: InterstitialAd.testAdUnitId,
  targetingInfo: targetingInfo,
  listener: (MobileAdEvent event) {
    print("InterstitialAd event is $event");
  },
);
```

Ads must be loaded before they're shown.
```
myBanner
  // typically this happens well before the ad is shown
  ..load()
  ..show(
    // Positions the banner ad 60 pixels from the bottom of the screen
    anchorOffset: 60.0,
    // Banner Position
    anchorType: AnchorType.bottom,
  );
```

```
myInterstitial
  ..load()
  ..show(
    anchorType: AnchorType.bottom,
    anchorOffset: 0.0,
  );
```

`BannerAd` and `InterstitialAd` objects can be disposed to free up plugin
resources. Disposing a banner ad that's been shown removes it from the screen.
Interstitial ads, however, can't be programmatically removed from view.

Banner and interstitial ads can be created with a `MobileAdEvent` listener. The
listener can be used to detect when the ad has actually finished loading
(or failed to load at all).

## Using rewarded video ads

Unlike banners and interstitials, rewarded video ads are loaded one at a time
via a singleton object, `RewardedVideoAd.instance`. Its `load` method takes an
AdMob ad unit ID and an instance of `MobileAdTargetingInfo`:
```
RewardedVideoAd.instance.load(myAdMobAdUnitId, targetingInfo);
```

To listen for events in the rewarded video ad lifecycle, apps can define a
function matching the `RewardedVideoAdListener` typedef, and assign it to the
`listener` instance variable in `RewardedVideoAd`. If set, the `listener`
function will be invoked whenever one of the events in the `RewardedVideAdEvent`
enum occurs. After a rewarded video ad loads, for example, the
`RewardedVideoAdEvent.loaded` is sent. Any time after that, apps can show the ad
by calling `show`:
```
RewardedVideoAd.instance.show();
```

When the AdMob SDK decides it's time to grant an in-app reward, it does so via
the `RewardedVideoAdEvent.rewarded` event:
```
RewardedVideoAd.instance.listener =
    (RewardedVideoAdEvent event, [String rewardType, int rewardAmount]) {
  if (event == RewardedVideoAdEvent.rewarded) {
    setState(() {
      // Here, apps should update state to reflect the reward.
      _goldCoins += rewardAmount;
    });
  }
};
```

Because `RewardedVideoAd` is a singleton object, it does not offer a `dispose`
method.

## Limitations

This is just an initial version of the plugin. There are still some
limitations:

- Banner ads have limited positioning functionality. They can be positioned at the top or the bottom of the screen and at a logical pixel offset from the edge.
- Banner ads cannot be animated into view.
- It's not possible to specify a banner ad's size.
- There's no support for native ads.
- The existing tests are fairly rudimentary.
- There is no API doc.
- The example should demonstrate how to show gate a route push with an
  interstitial ad

For Flutter plugins for other Firebase products, see
[FlutterFire.md](https://github.com/flutter/plugins/blob/master/FlutterFire.md).
