Send Push Notifications from AWS Lambda to a Flutter App for iOS and Android

Aidan Davis
4 min readJan 18, 2021

Hello, first blog. I want to try give back to the Flutter community a bit since I’ve been using it for years and haven’t been active in the community.

I’m going to explain how I did what it says in the title. I spent a lot of time googling and couldn’t find a single comprehensive post on it. AWS devs seem to hate proper documentation, I think so they can sell AWS qualifications.

You will need:

  • An existing flutter app (I’m assuming you are building for both ios and android, but if not just ignore the bits specific to the platform you aren’t using)
  • An AWS account
  • A Google account (as this solution uses Firebase for both ios and android)
  • An Appstore account
  • A real iphone (not a sim, for testing notifications)
  • An android phone (can be a sim, also for testing)
  • A macbook or similar, because Apple only lets you build ios apps using macos

We’ll start with the cloud stuff. Here’s a summary:

Lambda -> SNS -> Firebase Cloud Messaging -> (Apple Push Notification Service) -> Flutter app

Lambda

Trigger your lambda however you want! (Mine is triggered by an iot message). I’ve trimmed this down to be as straight-forward as possible. I’ll add some things to note beneath this gist.

Note: The above doesn’t include updating the badge count, or getting the ARN above. Here’s how I achieved those. You’ll also need to grant your lambda SNS write access (and DynamoDB if you use it).

The ARN is something I’ve stored in DynamoDB, under the user table. Add
var ddb = new AWS.DynamoDB({ apiVersion: ‘2012–08–10’ }); to imports at the top of the lambda.

The badge count is what is displayed on the app badge on iOS. You’ll need to keep a record of this and increment it each time you send a notification. In the app you’ll then reset this count when the user opens it. I get it at the same time I get the ARN above, and incrememnt it after the promise for sending the message resolves. Any issues I can share a gist of this too.

SNS and FCM

AWS SNS is Simple Notification Service. FCM is Firebase Cloud Messaging. SNS can send sms, email, whatever. Importantly it can send push notifications! Since we want them to go to both ios and android versions of the same app, the only simple solution is to use FCM and the FCM library for Flutter.

SNS will send the send the message to FCM, which is basically a relay service to the devices running the app. SNS manages the unique device identifier and provides it to FCM for FCM to deliver.

Let’s set up Firebase first. Create a project and do the following three things then stop. If you’re already using firebase you can skip them all.

For Apple devices, FCM will need to send the message to Apple’s server first which then sends it out. Since they make it easy you only need to follow these short instructions: https://firebase.flutter.dev/docs/messaging/apple-integration

I *think* for android you don’t have to do anything else. Again any issues let me know.

Now we have to link SNS to FCM.

  1. In the Firebase console, Cloud Messaging tab under Project Settings, click Add server key and copy the details.
  2. In SNS, click Push notifications then Create platform application. Push notification platform is Firebase Cloud Messaging and API key is what you copied above.

Keep this SNS tab open; we’ve finished the cloud stuff now and will move on to the app code.

The App

The app uses FCM to receive push notifications. Set this up now: https://firebase.flutter.dev/docs/messaging/overview — and just stick to the v2 embedding. You should only be adding a single line to the pubspec.yaml at this point.

The first thing you have to do in your app is initialise Firebase. This is the best way I’ve found to do it as early as possible.

I am going to skip logging a user in to AWS with Cognito — I have that planned for another post. What that will give you is a unique userID, referred to as the userSub, and cognito credentials (used for authenticating requests with AWS). For credentials I rely heavily on this package. I’m also not covering the requests to DynamoDb here.

Once the user has logged in, run the code to set up the notifications. The best documentation for this is literally psuedocode and some java written based off that psuedocode. I’ve converted it into dart functions (you’re welcome).

First step is to request permissions. Add await FirebaseMessaging.instance.requestPermission(sound: true, badge: true, alert: true,); before calling the method in the following gist. I’m presenting it this way as you’ll call the following method multiple times but requesting permissions only happens once.

This gist is essentially the psuedocode from the documentation linked above. It’s missing the http classes that actually interact with SNS. They are done the same way you’d interact with DynamoDB, S3, etc. through http (link to documentation below).

I’m hesitant to turn this article into a wall of code, so reach out if you want to see more detail. For the http requests alluded to above, here is a good place to start: https://docs.aws.amazon.com/sns/latest/api/API_GetEndpointAttributes.html

Testing

Fire up your lambda and see what happens! Remember on ios you’ll need a physical device as the sim doesn’t receive notifications.

--

--

Aidan Davis

Software Developer. SAP Fiori and ABAP. Flutter and web on the side.