FCM (Firebase Cloud Messaging)AWS Pinpoint を使ってFlutterアプリにプッシュ通知を送る際に問題となるのが、「Pinpointのエンドポイントにデバイストークンを登録すること」です。
現状Flutter Amplifyライブラリーには、デバイストークンをPinpointのエンドポイントに登録する機能がありません。ここではそれの解決策を記載します。
※認証機能としてCognitoを使用

流れ

  1. Fluttter Amplify analiticsでユーザ情報をPinpointへ送信
  2. AWS Signature Version 4パッケージの導入
  3. 2のパッケージを利用してREST通信を行う

ユーザ情報をPinpointへ送信

AmplifyライブラリーのAnalisticを使用してユーザ情報をPinpointへ送信。

//例
Future<void> identify User async{
  final location = AnalyticsUserProfileLocation()
    ..city = 'Tokyo'
    ..region = '<YOUR-REGION>'
    ..country = 'JPN';
  final userProfile = AnalyticsUserProfile();
  userProfile.name = "ユーザID";
  userProfile.location = location;

  await Amplify.Analytics.identifyUser(
    userId: userId,
    userProfile: userProfile,
  );
}"

AWS Signature Version 4パッケージの導入

pubspeck.yamlファイルにaws_signature_v4を追加。

AWS HTTP GETメソッドを使用してエンドポイントIDを取得

URLにアプリケーションIDとユーザIDを付与。
結果エンドポイントIDを取得出来る。

import 'dart:convert';
import 'package:aws_common/aws_common.dart';
import 'package:aws_signature_v4/aws_signature_v4.dart';

// Create the signer instance with credentials from the environment.
const signer = AWSSigV4Signer(
      credentialsProvider: AWSCredentialsProvider(AWSCredentials(
          "ACCESS_KEY", "SECRET_KEY")),
  );

// Create the signing scope and HTTP request
const region = '<YOUR-REGION>';

final request = AWSHttpRequest.get(
    Uri.https('pinpoint.<YOUR-REGION>.amazonaws.com', '/v1/apps/<application-id>/users/<user-id>'),
    headers: {
      AWSHeaders.target: 'AWSCognitoIdentityProviderService.DescribeUserPool',
      AWSHeaders.contentType: 'application/json',
    },
  );

// Sign and get the HTTP request
final signedRequest = await signer.sign(
  request,
  credentialScope: scope,
);
final resp = await signedRequest.send();
final respBody = await resp.decodeBody();
print(respBody);

上記で得たエンドポイントへデバイストークンを追加

/v1/apps/application-id/endpoints/endpoint-id

final uploadRequest = AWSHttpRequest.put(
    Uri.https('pinpoint.<YOUR-REGION>.amazonaws.com', '/v1/apps/<application-id>/endpoints/endpoint-id'),

    headers: const {
    AWSHeaders.target: 'AWSCognitoIdentityProviderService.DescribeUserPool',
    AWSHeaders.contentType: 'application/json',
  },
  body: json.encode({
    //GCM for ANDROID, APNS for iOS
    "ChannelType": <GCM/APNS>,
    "Address": "<YOUR-DEVICE-TOKEN>",
    "Location": {
        "Region": "<YOUR-REGION>",
        "Country": "JPN"
      },
    "OptOut": "NONE",
    "User": {
    "UserId": "string",
    }
  }).codeUnits,
);

// Sign and send the HTTP request
final signedRequest = await signer.sign(
  request,
  credentialScope: scope,
);
final resp = await signedRequest.send();
final respBody = await resp.decodeBody();
print(respBody);```

以上、みなさんの参考になれば幸いです。

さいごに