FlutterでAmplify Analytics(pinpoint)を使ってみる

# 概要
本記事では、FlutterでAmplify Analytics(中身はAmazon pinpoint)を動かします。

Flutterでログ情報を集めるには、従来だとGoogle Analytics for Firebase(以下、GAと呼ぶ)のほぼ一択だったかと思います。

GAで計測していても、どうにも実際のイベント数と合わない気がしたので、一度他のプロダクトを使ってみようということでAmplify Analyticsを採用してみました。
Flutter Amplifyの[公式doc](https://docs.amplify.aws/lib/analytics/getting-started/q/platform/flutter/)は一部不親切だと感じた部分があり、自分なりに整理してみました。

# 環境
flutter, Amplify CLIのインストールは別記事を参照お願いします。

```shell
$ flutter --version
Flutter 2.10.4 • channel stable • https://github.com/flutter/flutter.git
Framework • revision c860cba910 (3 weeks ago) • 2022-03-25 00:23:12 -0500
Engine • revision 57d3bac3dd
Tools • Dart 2.16.2 • DevTools 2.9.2

$ amplify -v
8.0.0
```

# 事前準備
## プロジェクト作成【作成済であれば不要】
プロジェクト名のflutter_amplify_analyticsやオプションについては、適宜変更してください。
```shell
$ flutter create flutter_amplify_analytics
```

## プラットフォームのバージョン指定
### iOS
Podfileのplatformのコメントを外してiosのバージョンを13.0に指定します。
13.0の理由は、[Amplify公式](https://docs.amplify.aws/start/getting-started/setup/q/integration/flutter/#add-amplify-to-your-application)を参照しています。
```text:ios/Podfile
platform :ios, '13.0'
```

### Android
```gradle:android/app/build.gradle
minSdkVersion 21
```

以下は参考です。[公式](https://docs.amplify.aws/start/getting-started/installation/q/integration/flutter/)によると、【1.5.31】以上であることが必須らしいですが、Flutterのバージョン3.10.xは、何もしなくてもKotlinのバージョンが1.5.31以上で設定されているので気にしなくて良いです。
```gradle:android/build.grdale
buildscript {
    ext.kotlin_version = '1.6.10'
    ...
}
```
# 実装
## バックエンド構築
まずは、プロジェクトのルートで以下のコマンドを叩きます。
色々聞かれますが、あなたの環境に合わせて適宜入力ください。
```shell
$ amplify init
```
次に、今回利用するPinpointを利用するために、以下叩きます。
その後、Pinpointを選択し、その後も質問されますが、適宜ユースケースに応じて変更してください。
※今回は、プロジェクト名そのまま、認証してないユーザのイベントも取得したいため、Yesを選択

```shell
$ amplify add analytics
$ ? Select an Analytics provider (Use arrow keys)
❯ Amazon Pinpoint 
$ ? Provide your pinpoint resource name: (【あなたのプロジェクト名】)
? Apps need authorization to send analytics events. Do you want to allow guests and unauthenticated users to send analytics events? (we reco
mmend you allow this when getting started) (Y/n) Yes
```

成功すると、以下が表示されます。

```shell
✅ Successfully added auth resource locally.
Successfully added resource flutteramplifysample locally
```

その後、忘れずにamplify pushで反映させましょう。

```shell
$ amplify push
```

## フロントエンド構築
### プラグイン取り込み
プロジェクトのルートで以下のコマンドを叩きます。

※注意!!!公式docだと、「amplify_flutter」と「amplify_analytics_pinpoint」しか記載ありませんが、
「amplify_auth_cognito」を入れなければ、エラー出ます(※1)。
※公式docのdependencyに記載ない上に、直接cognitoプラグインのメソッド呼ぶこともないことから、不要だと思い込んでしまい、ハマってしまっていました。。。
※おそらく、amplify_analytics_pinpointの中でamplify_auth_cognitoの関数か何か呼んでるものと予想しています。

```shell
$ flutter pub add amplify_flutter
$ flutter pub add amplify_analytics_pinpoint
$ flutter pub add amplify_auth_cognito←✨✨忘れないように!!
$ flutter pub get ←たまに忘れがち!!
```

pubscpec.yamlを直接以下のように変更しても構いません。
※バージョンは本記事記載時点では、0.4.5が最新でした。

```yaml:/pubspec.yaml
dependencies:
  flutter:
    sdk: flutter

  amplify_flutter: ^0.4.5
  amplify_analytics_pinpoint: ^0.4.5
  amplify_auth_cognito: ^0.4.5 ←✨✨公式docに記載ないがcognitoも必要。要注意!!
```

※1: amplify_auth_cognitoに入れずに動かすと以下エラーが表示される。
```shell:
Amplify/AuthCategory.swift:27: Fatal error: No plugins added to Authentication category.
```

### amplifyの初期化
MyAppをStatefulWidgetに変換し、initStateで設定を読み込みます。
※Mac x Android Studioの場合はOption+Enterのショートカットキーの[Convert to StatefulWidget]がおすすめ

```dart:/lib/main.dart
import 'package:amplify_analytics_pinpoint/amplify_analytics_pinpoint.dart';
import 'package:amplify_flutter/amplify_flutter.dart';

class MyApp extends StatefulWidget {
  // This widget is the root of your application.
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    _configureAmplify();
  }

  void _configureAmplify() async {
    // Add the following line to add Pinpoint and Cognito plugin to your app
    Amplify.addPlugins([AmplifyAuthCognito(), AmplifyAnalyticsPinpoint()]);

    try {
      await Amplify.configure(amplifyconfig);
    } on AmplifyAlreadyConfiguredException {
      print(
          "Tried to reconfigure Amplify; this can occur when your app restarts on Android.");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
```

### イベント登録
今回はデフォルトで作成されるカウンターアプリのFABでタップされた時にイベント登録するようにします。
オプションは適当です。適宜ユースケースに合わせて修正してください。

```dart:/lib/main.dart
void _incrementCounter() {
    AnalyticsEvent event = AnalyticsEvent('FAB_Tap');

    event.properties.addBoolProperty('boolKey', true);
    event.properties.addDoubleProperty('doubleKey', 10.0);
    event.properties.addIntProperty('intKey', 10);
    event.properties.addStringProperty('stringKey', 'stringValue');

    Amplify.Analytics.recordEvent(event: event);
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }
```

### 確認
```shell
amplify console analytics
```

でイベント発火した結果を確認することができます。
今回、サンプルで作成した結果を以下に例示します。

![スクリーンショット 2022-04-14 12.53.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1424230/fb2a0edc-ba06-e5d4-3262-0de9862d642d.png)

# おまけ(比較しての感想）
単純なイベント送信は、Google Analyticsと比べて、実装難易度に正直違いはあまり感じませんでした。
コンソールのUIのリッチさはGoogle Analyticsに軍配が上がりますが、個人的にはシンプルなAmplify Analyticsの方が好みです。
使用感については皆様も一度使ってみて、比較してみるのもいいかもしれません。