flutterでアプリ公開してからadmob導入するまで

---
# :book: Flutterの記事を整理し本にしました :book:
https://zenn.dev/kazutxt/books/flutter_practice_introduction

* <font color="red"><b>本稿の記事を含む様々な記事を体系的に整理し本にまとめました</b></font>
* 今後はこちらを最新化するため、<font color="red"><b>最新情報はこちらをご確認くださ</b>い</font>
* 10万文字を超える超大作になっています(笑)

---

# はじめに
* 最近Flutterを使って、Android/iOS向けにアプリをリリースしています。
* その中で、adMob(広告)をつける際のノウハウをまとめました。

## まとめ記事
* [Flutter系の記事のまとめ](https://qiita.com/kazutxt/items/524acb1c134015682ccf)

## リリースするまでの関連記事
* [Flutterで作ったアプリをAndroidとiOSとWebに同時にリリースする(Android編)](https://qiita.com/kazutxt/items/66d52d78ec1349f2b249)
* [Flutterで作ったアプリをAndroidとiOSとWebに同時にリリースする(Webアプリ編)](https://qiita.com/kazutxt/items/e86bec4d335488a8baa0)
* [Flutterで作ったアプリをAndroidとiOSとWebに同時にリリースする(iOS編)](https://qiita.com/kazutxt/items/0ea523d5ccf647c144ad)

# google_mobile_ads(追記)
* 2021/3/3のflutter engageでflutter2の発表と同時に、google_mobile_adsが発表されました。
* こちらはwidgetツリーの中に組み込める(オーバレイではない)うえに、様々な改良が行われているようですので、今後はこちらが良いかと思います。
    * すでにadmobで利用されている場合は問題ないと思いますが、今後バージョンアップなどの更新が行われない可能性もありますのでご注意ください
* google_mobile_adsの設定の仕方などはこちらの記事をご参照ください
    * [flutterアプリでfirebase_admobからgoogle_mobile_adsに切り替えてみた](https://qiita.com/kazutxt/items/8ea0eab5dfac2c59366d)
 
※2021/03/11 追記

# 0.事前準備
* firebaseとadmobのアカウントは作成済で、利用できる状態を前提としています
* ~~作成したアプリがGooglePlay/AppStoreに公開されている状態を前提としています~~
* 公開に時間がかかるので事前に登録しておき、あとから紐づける方が効率が良いようので、記事に追記しています。


# 1.adMobにアプリを登録
* Firebase > adMob > アプリ登録の画面でアプリを検索します。
![スクリーンショット 2020-10-24 11.33.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/92289da8-1b4e-b620-8ef1-b02d2ca6b431.png)


* 今回は「コツコツ」というアプリを使ってご説明します
* AppStoreの方は、公開後5日～1週間程度の時間差があるので注意が必要です。
* 追加ボタン後は、案内に従ってアプリIDと広告IDを払い出します。
    * GooglePlayとAppStoreで別々に行う必要があります
    * 設定する内容などは同じです

![スクリーンショット 2020-10-24 11.33.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/c2156db9-488c-7a2e-c945-2ad66a0d9aca.png)
![スクリーンショット 2020-10-24 11.34.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/48af0948-d5f6-d5e8-d235-8f941ca04c23.png)
ガイドに従っていくと、アプリIDと広告ユニットIDが払い出されます。
これをあとでアプリ側で設定して紐付けを行います。

# 2.Firebaseとの紐付け
## Android
* FirebseでAndroidプロジェクトを紐付けます

![スクリーンショット 2020-10-24 11.41.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/ee040e4d-1b11-3a4f-195c-3292c4e3c9a8.png)

* アプリの登録で、androidパッケージ名を入れます。
    * このパッケージ名は、プロジェクトで設定しているものと一致させる必要があります
    * パッケージ名は、android/app/main/AndroidManifest.xmlのにあるpackage=の部分になります。 

![スクリーンショット 2020-10-24 12.00.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/3f9b98b3-a751-c573-bbf1-0a34383c276c.png)
![スクリーンショット 2020-10-24 12.00.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/2ba57038-3c81-65c3-6867-e5ea37086218.png)

* ダウンロードしたgoogle-services.jsonを、android/appの下に配置します。
    * このファイルは加工する必要はありません。単純に配置するだけです

### パッケージ名の変え方
このとき、パッケージ名がcom.example.{プロジェクト名}になっている場合は、変えておくほうが無難です。

一括に変える方法が思いつかないので、対応する場所を変えていきます

* android/app/main/AndroidManifest.xml　-> package=の部分
* android/app/debug/AndroidManifest.xml -> package=の部分
* android/app/profile/AndroidManifest.xml -> package=の部分
* android/app/src/main/kotlin/com/{XXX} ->  パッケージのフォルダ名
* android/app/src/main/kotlin/com/{XXX}/MainActivitly.kotlin ->  package 

ファイルの配置以外にも3点設定箇所があります

```android/app/main/AndroidManifest.xml
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-***"/>
```

* 広告IDではなく、アプリのIDなので注意が必要です

```android/build.gradle
dependencies{
    classpath 'com.google.gms:google-services:4.3.3'
}
```

```android/app/build.gradle
apply plugin: 'com.google.gms.google-services'
```

## iOS
* iOSも同じように登録します。bundleIDを一致させることには注意してください
![スクリーンショット 2020-10-24 19.31.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/8816268b-a4b7-e77f-fc5c-65fd2076499e.png)

* 必ずXCodeで行ってください。VSCodeで単純にコピーしても参照などがうまく作られないようです

ファイルの配置以外にも1点設定箇所があります

``` iOS/Runner/Info.plist
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-***</string>
```

# 3.ソースコードの修正

* まずライブラリを追加します

``` pubspec.yaml
firebase_admob: ^0.10.0 # 最新バーションに合わせて修正
```
## 追記 (2021/3/3)
* admobのバージョンを”0.11.0+1”にしたところビルドエラーになり、Gradleのバージョンを上げたら動作するというのがありました。
* 参考記事
    * https://stackoverflow.com/questions/65857643/exception-the-plugin-firebase-admob-could-not-be-built-due-to-the-issue-above
    
<追記ここまで>

``` android/build.gradle
    dependencies {
        //3.5.0だとadmob0.11が動かないので、3.5.4に修正
        classpath 'com.android.tools.build:gradle:3.5.4'
        //classpath 'com.android.tools.build:gradle:3.5.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.gms:google-services:4.3.3'
    }
```


* 続いて、ソースコードに設定を記載します
* 先に、Managerクラスを作って、IDなどはこちらで管理するようにします

``` AdManager.dart
import 'dart:io';

class AdManager {
  // アプリIDを返す関数
  static String get appId {
    if (Platform.isAndroid) {
      return "XXX"; //AndroidのアプリID
    } else if (Platform.isIOS) {
      return "XXX"; //iOSのアプリID
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  // 広告ユニットIDを返す関数
  static String get bannerAdUnitId {
    if (Platform.isAndroid) {
      return "XXX";  // Androidの広告ユニットID
    } else if (Platform.isIOS) {
      return "XXX";  // iOSの広告ユニットID
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }
}

```

* ではいよいよ、mainのほうに広告を出す設定をします
    * 結構シンプルです


``` main.dart
// インポート部分
import 'package:firebase_admob/firebase_admob.dart';
import 'package:{AdManagerを定義したファイル}';

class MyClass {
    // バナー用の変数
    BannerAd myBanner;

    @override
    void initState(){
        // 初期化
        FirebaseAdMob.instance.initialize(appId:AdManager.appId);
        // インスタンスの作成
        myBanner = BannerAd(
            //adUnitId: BannerAd.testAdUnitId, // テスト用
            adUnitId: AdManager.bannerAdUnitId, // 本番用
            size: AdSize.smartBanner, // 目的のサイズに合わせる
            listener: (MobileAdEvent event) {
                print("BannerAd event is $event");
            },
        );
        // 表示
        myBanner
          ..load()
          ..show(anchorType: AnchorType.bottom);
        // その他のinitstate
    }

    @override
    void dispose(){
        // 廃棄
        myBanner?.dispose();
        // その他のdispose
    }

}
```
## テスト用ID
2021/3/3追記

下記の通り、テスト用のIDが準備されていますので、まずはこちらを使われるのが良いかと思います。
リリース前に差し替えるのを忘れないようにだけ注意してください

* アプリID
    * Android: ca-app-pub-3940256099942544~3347511713
    * iOS: ca-app-pub-3940256099942544~1458002511
* 広告ユニットID
    * Android: ca-app-pub-3940256099942544/6300978111
    * iOS: ca-app-pub-3940256099942544/2934735716

なお、admobのプラグインにて、定数定義がありますので、
`FirebaseAdMob.testAppId`や`BannerAd.testAdUnitId`のように利用することも可能です。

# 事前にIDを払い出しあとから紐付ける方法(追記)
* アプリストアに掲載されていますか？でいいえを選択し、アプリ名を入れます
![pic1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/f9d08de4-2fa8-7841-04b0-81612aff6b1d.png)

* アプリストアに掲載された後に、アプリの設定からアプリストの追加で、紐付けを行います。
![pic1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/55c029c6-26ea-22ab-9b87-2d9a02fafba0.png)

* <b><font color ="red">この方法だと、初回リリース前にadmobの確認ができますし、リリース作業が1回で済みます!!</font></b>

# 備考
* 再アップロードの際には、バージョンアップが必要です

``` pubspec.yml
version:1.0.0+1
```
この部分を1.0.1+2などに変更しないと、バージョンが同じでエラーになります。
1.0.1がバージョンで、2がバージョンコード。になります。



# 参考文献
* https://codelabs.developers.google.com/codelabs/admob-ads-in-flutter#0

# 宣伝
* [スマートツールシリーズ](https://smart-simple-tools.kazutxt.com)
* [GooglePlay](https://play.google.com/store/apps/developer?id=kazutxt)
* [AppleSotre](https://apps.apple.com/us/developer/kazuaki-kakeuchi/id1534560455)