FCM (Firebase Cloud Messaging)
と AWS Pinpoint
を使ってFlutterアプリにプッシュ通知を送る際に問題となるのが、「Pinpointのエンドポイントにデバイストークンを登録すること」です。
現状Flutter Amplifyライブラリーには、デバイストークンをPinpointのエンドポイントに登録する機能がありません。ここではそれの解決策を記載します。
※認証機能としてCognitoを使用
流れ
- Fluttter Amplify analiticsでユーザ情報をPinpointへ送信
- AWS Signature Version 4パッケージの導入
- 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);```
以上、みなさんの参考になれば幸いです。
さいごに