DEV Community

Cover image for Push Notification using Amazon Pinpoint in Flutter
Monikinderjit Singh
Monikinderjit Singh

Posted on • Originally published at monik.hashnode.dev

1 1

Push Notification using Amazon Pinpoint in Flutter

Amazon Web Services, in early 2021, extended its support for Flutter, which is quite amazing and many new startups have started to use AWS in their flutter applications due to its ease of scalability and support. Amazon Web Service offers a wide variety of options for Flutter, but we're going to focus on Amazon Pinpoint Service today.

Amazon Pinpoint allow users to send push notifications to multiple recipients. To increase sales, companies and organizations can use marketing campaigns to contact their clients.

Let's figure out how to integrate this into your Flutter application.

What we are going to use💻?

To start, we need to install the following packages:

Setup Amplify Pinpoint

  1. To install pinpoint in your amplify project, you will need to add amplify analytics service to your flutter project.
  2. Run amplify add analytics in your terminal (Make sure you are at root of the project)
    Screenshot_20210824_173824.png

  3. Select Amazon Pinpoint service and then give a name to your pinpoint service resource.
    Screenshot_20210824_173855.png

  4. Press Y and then click enter. Your amazon pinpoint service will be added locally.
    Screenshot_20210824_175120.png

  5. Now, to publish it in the cloud, run amplify push.

Point to be noted: It takes time for amazon analytics to start recording the events. For me, I was able to record events the next morning.

To send notifications from pinpoint, we will need to set up a module that will interact with the app to show the notification. To fulfil this, we have to use Firebase Cloud Messaging Service which will send our notification triggered from Amazon Pinpoint to the user.

Set up Firebase Cloud Messaging

Firebase Console Setup:

  1. Open Firebase Console
  2. Click on Create Project image.png
  3. Give a name to your project and press continue.
  4. Make sure analytics is enabled and then press continue. image.png
  5. Select your country and then create your project.
  6. Register your app and follow the steps described there to successfully register the app. image.png > Extra focus on initializing firebase SDK and google-services.json file
  7. After your app has been registered, go to Engage->Cloud Messaging. image.png

Let's write some code

via GIPHY

Make a file named notifications. dart and add the following file. In this file, we are handling our notifications from the amazon pinpoint service.

import 'dart:developer';
import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
if (message.data != null) {
log("====hey");
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
Map<String, dynamic> pinpointMessage = message.data;
if (flutterLocalNotificationsPlugin == null) {
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
}
if (pinpointMessage["pinpoint.notification.imageUrl"] != null &&
pinpointMessage["pinpoint.notification.imageIconUrl"] != null) {
log("h2");
return NotificationHandler().showBigPictureNotification(pinpointMessage);
} else if (pinpointMessage["pinpoint.notification.imageUrl"] != null) {
return NotificationHandler()
.showBigPictureNotificationHiddenLargeIcon(pinpointMessage);
} else
flutterLocalNotificationsPlugin.show(
pinpointMessage["pinpoint.campaign.campaign_id"].hashCode,
pinpointMessage["pinpoint.notification.title"],
pinpointMessage["pinpoint.notification.body"],
NotificationDetails(
android: AndroidNotificationDetails(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.high,
icon: null, // android?.smallIcon,
// other properties...
),
));
}
}
class NotificationHandler {
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
late AndroidNotificationChannel channel;
NotificationHandler() {
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
// if (!kIsWeb) {
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.high,
);
var initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
var initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
flutterLocalNotificationsPlugin.initialize(
initializationSettings,
);
/// Create an Android Notification Channel.
///
/// We use this channel in the `AndroidManifest.xml` file to override the
/// default FCM channel to enable heads up notifications.
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
getToken();
}
Future<void> getToken() async {
var token = await FirebaseMessaging.instance.getToken();
log("$token");
}
Future<void> firebaseMessagingForegroundHandler(RemoteMessage message) {
Map<String, dynamic> pinpointMessage = message.data;
if (pinpointMessage["pinpoint.notification.imageUrl"] != null &&
pinpointMessage["pinpoint.notification.imageIconUrl"] != null) {
log("h2");
return showBigPictureNotification(pinpointMessage);
} else if (pinpointMessage["pinpoint.notification.imageUrl"] != null) {
return showBigPictureNotificationHiddenLargeIcon(pinpointMessage);
} else
return flutterLocalNotificationsPlugin.show(
pinpointMessage["pinpoint.campaign.campaign_id"].hashCode,
pinpointMessage["pinpoint.notification.title"],
pinpointMessage["pinpoint.notification.body"],
NotificationDetails(
android: AndroidNotificationDetails(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.high,
icon: null,
),
));
}
Future<void> showBigPictureNotification(
Map<String, dynamic> pinpointMessage) async {
final String largeIconPath = await _downloadAndSaveFile(
pinpointMessage["pinpoint.notification.imageIconUrl"], 'largeIcon');
final String bigPicturePath = await _downloadAndSaveFile(
pinpointMessage["pinpoint.notification.imageUrl"], 'bigPicture');
final BigPictureStyleInformation bigPictureStyleInformation =
BigPictureStyleInformation(FilePathAndroidBitmap(bigPicturePath),
largeIcon: FilePathAndroidBitmap(largeIconPath),
contentTitle:
'<b>${pinpointMessage["pinpoint.notification.title"]}</b>',
htmlFormatContentTitle: true,
summaryText: '${pinpointMessage["pinpoint.notification.body"]}',
htmlFormatSummaryText: true);
final AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails('big text channel id',
'big text channel name', 'big text channel description',
styleInformation: bigPictureStyleInformation);
final NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
pinpointMessage["pinpoint.campaign.campaign_id"].hashCode,
pinpointMessage["pinpoint.notification.title"],
pinpointMessage["pinpoint.notification.body"],
platformChannelSpecifics);
}
Future<void> showBigPictureNotificationHiddenLargeIcon(
Map<String, dynamic> pinpointMessage) async {
final String bigPicturePath = await _downloadAndSaveFile(
pinpointMessage["pinpoint.notification.imageUrl"], 'bigPicture');
final BigPictureStyleInformation bigPictureStyleInformation =
BigPictureStyleInformation(FilePathAndroidBitmap(bigPicturePath),
hideExpandedLargeIcon: true,
contentTitle:
'<b>${pinpointMessage["pinpoint.notification.title"]}</b>',
htmlFormatContentTitle: true,
summaryText: '${pinpointMessage["pinpoint.notification.body"]}',
htmlFormatSummaryText: true);
final AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails('big text channel id',
'big text channel name', 'big text channel description',
styleInformation: bigPictureStyleInformation);
final NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
pinpointMessage["pinpoint.campaign.campaign_id"].hashCode,
pinpointMessage["pinpoint.notification.title"],
pinpointMessage["pinpoint.notification.body"],
platformChannelSpecifics);
}
Future<String> _downloadAndSaveFile(String url, String fileName) async {
final Directory directory = await getApplicationDocumentsDirectory();
final String filePath = '${directory.path}/$fileName';
final http.Response response = await http.get(Uri.parse(url));
final File file = File(filePath);
await file.writeAsBytes(response.bodyBytes);
return filePath;
}
}

In main.dart file, call this function _configureAmplify() inside init state

import 'package:amplify_analytics_pinpoint/amplify_analytics_pinpoint.dart';
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_flutter/amplify.dart';
void _configureAmplify() async {
if (!mounted) return;
AmplifyAuthCognito authPlugin = AmplifyAuthCognito();
AmplifyAnalyticsPinpoint analyticsPlugin = AmplifyAnalyticsPinpoint();
Amplify.addPlugins([authPlugin, analyticsPlugin]);
try {
await Amplify.configure(amplifyconfig);
setState(() {
_amplifyConfigured = true;
});
} catch (e) {
print(e);
}
}

and add these lines in main() function.

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import '../notification_handler.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
NotificationHandler? _notificationHandler = NotificationHandler();
try {
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
} catch (e) {
print(e);
}
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
log("${message.data}");
if (message.data != null) {
log("hey");
_notificationHandler.firebaseMessagingForegroundHandler(message);
}
});
runApp(MyApp());
}
view raw main.dart hosted with ❤ by GitHub

It's all. Ohh, wait. Let's check how to trigger our notification from Amazon Pinpoint Service.

Make a notification from Pinpoint Service Webpage

  1. Go to your pinpoint service page from your amplify admins page and then click on the pinpoint service you created. Click on Settings->Push Notifications and enable Firebase Cloud Messaging (FCM). After enabling, there will be a green tick as shown below.
    Screenshot_20210824_171228.jpg

  2. Go to Test Messaging and click on Push Notifications. To send a message we will be requiring a google device token which we are getting using the getToken() function in the requirements.dart file. Without this token, we will not be able to send our message.
    Write this token inside the Device tokens field.
    Screenshot_20210824_171101.jpg

  3. Write a message, add a picture URL and send this to the user.
    Screenshot_20210824_171142.jpg

Kudos 🎉🎉

Congratulations to everyone who was able to send their first pinpoint service to trigger the notification. Despite it being a long tutorial, you all made it to the end.

Little Bit About Me🧑‍💻🧑‍💻🧑‍💻

Hey developers, I'm Monikinderjit Singh, working on Flutter for more than a year now. My interest in cloud technology is fueled by my need to learn more about it. I am currently new to hashnode (this is my second blog post). I would appreciate you giving it a like if you find it interesting and leaving a comment if you have a better solution for this topic. It would be awesome if you could give me some feedback on improving my content.
You can connect with me on my Twitter, Github and LinkedIn .

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

AWS GenAI LIVE!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️