Front-End Web & Mobile

Announcing AWS Amplify Flutter (Developer Preview)

This post was written by Ashish Nanda, Software Development Engineer, AWS Amplify

The popularity of cross-platform mobile development in general, and the Flutter ecosystem in particular, has been growing rapidly over the last few years. Developers are increasingly looking to build immersive and feature-rich, cloud powered applications for multiple platforms using a single framework and codebase.

AWS Amplify is a set of tools and services that enables mobile and front-end web developers to build secure, scalable full stack applications powered by AWS. It consists of three main components: a set of open source libraries and UI components for adding cloud-powered functionalities, a CLI toolchain to create and manage cloud backends, and the Amplify Console, an AWS Service to deploy and host full stack serverless web applications. Currently Amplify supports iOS, Android, and JavaScript (Web and React Native) and is the quickest and easiest way to build applications powered by AWS cloud services.

Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase, and is one of the fastest growing mobile frameworks in 2020. With the increased adoption of the framework among mobile developers, enabling support for Flutter applications through a library and the CLI toolchain has been one of the most requested and highly anticipated additions to the Amplify Framework by customers.

Amplify Flutter

Today we are happy to announce the launch of Amplify Flutter in Developer Preview, which will allow developers to build Flutter apps using the same category-based programming model that Amplify iOS and Android provide. This enables developers to quickly create, configure, and integrate categories like Auth, Storage, and Analytics to build feature-rich full-stack applications for use cases such as signing in and signing up users, uploading and downloading files, and tracking user analytics.

Amplify provides developers with declarative, use case specific interfaces which as compared to generated or handwritten service-specific SDKs (which are currently not officially available for Dart) results in a better, more intuitive developer experience with built-in best practices and convention over configuration. This leads to faster development with less lines of code, and is our recommended way to build mobile applications powered by the AWS cloud.

Design and Architecture

The Amplify Flutter library is designed as a collection of plugin packages for different categories. The use case-centric API interfaces to be integrated into your Flutter app are written in Dart and communicate with the platform-specific implementations that use Amplify iOS and Android under the hood. The communication is done using platform channels.
The library is also designed with a pluggable architecture in mind, which involves writing plugin interfaces in Dart for each category, that the plugins will then implement. Thus while currently all plugins use Amplify iOS and Android under the hood, this design allows for extensibility and keeps the door open to implementing plugins with Dart-only SDKs and even target different platforms like Web or Desktop in the future.

Currently Supported Categories

As part of the Developer Preview launch, the following categories are supported:

Auth: Provides an interface for authenticating a user and enables use cases like SignUp, SignIn, MFA etc. Behind the scenes, it provides the necessary authorization to the other Amplify categories. It comes with default, built-in support for Amazon Cognito User Pools and Identity Pools.

Storage: Provides an interface for managing user content for your app in public, protected, or private storage buckets. It enables use cases like upload, download and deleting objects and provides built-in support for Amazon Simple Storage Service (S3) by default.

Analytics: Enables you to collect tracking data for authenticated or unauthenticated users in Amazon Pinpoint. You can easily record events and extend the default functionality for custom metrics or attributes as needed.

Example Use Cases

In this section we go over some of the common use cases and APIs for the Auth, Storage, and Analytics categories. As you will see below the interfaces are use case based rather than service or provider specific.

Auth: Sign Up and Sign In

The code snippet below demonstrates how to sign up a user with their email, password and phone number, which is the default setup enabled with the Amplify CLI.

try {
  Map<String, dynamic> userAttributes = {
    'email': 'my@email.com' ,
    'phone_number': '+10123456789',
    // additional attributes as needed
  };
  SignUpResult res = await Amplify.Auth.signUp(
    username: 'myusername',
    password: 'mysupersecurepassword',
    options: CognitoSignUpOptions(
      userAttributes: userAttributes
    )
  );
  setState(() {
    _isSignUpComplete = res.isSignUpComplete;
  });
} on AuthError catch (error) {
  print(error);
}

Once sign up succeeds, and we confirm the user, the sign up flow is complete and we can go ahead and sign in a user with their username and password as shown below:

try {
  SignInResult res = await Amplify.Auth.signIn(
    username: 'myusername',
    password: 'mysupersecurepassword',
  );
  setState(() {
    _isSignedIn = res.isSignedIn;
  });
} on AuthError catch (error) {
  print(error);
}

Storage: Upload and Download File

The code snippet below demonstrates how to upload a file from a local filesystem path to S3 using the Storage.uploadFile API. Additionally, when uploading files using the Storage category, you can specify the access level for that file to be either guest (accessible by all users), protected, or private. The default access level for the Storage category is guest.

try {
  File local = await FilePicker.getFile(type: FileType.image);
  final key = 'myKey';

  S3UploadFileOptions options = S3UploadFileOptions(
      accessLevel: StorageAccessLevel.protected);

  UploadFileResult result = await Amplify.Storage.uploadFile(
      key: key, local: local, options: options);

  setState(() {
    _uploadFileResult = result.key;
  });
} catch (error) {
  print(error);
}

To generate a download URL for objects that have been uploaded to the Storage provider (S3), use the Storage.getUrl API as shown below:

try {
  final key = 'myKey';
  GetUrlResult result =
      await Amplify.Storage.getUrl(key: key);
  setState(() {
    _getUrlResult = result.url;
  });
} catch (error) {
  print(error);
}

Analytics: Record Events

The Amplify Analytics category provides a simple interface to record custom events within your app:

AnalyticsEvent event = AnalyticsEvent('PasswordReset');
event.properties.addStringProperty('Channel', 'SMS'); 
event.properties.addBoolProperty('Successful', true);
event.properties.addIntProperty('ProcessDuration', 792); 

Amplify.Analytics.recordEvent(event: event);

To learn more about all the use cases supported in Amplify Flutter as well as detailed setup steps, please refer to our documentation.

Getting Started

In this blog post, we talked about how we currently support the Auth, Analytics, and Storage categories in Amplify Flutter and walked through examples of how to use the library for some common use cases. For a step-by-step guide to setting up your backend resources using the Amplify CLI and integrating the library in a sample Flutter application, check out the getting started section of our docs.

What’s Next?

If you are curious about whats next on our roadmap, the list below captures the main features and categories we plan to release in the coming months:

API (REST/GraphQL): The API category provides an interface for retrieving and persisting your data, using GraphQL backed by AWS AppSync or REST APIs and handlers using Amazon API Gateway and AWS Lambda.

DataStore: Amplify DataStore provides a programming model for leveraging shared and distributed data without writing additional code for offline and online scenarios, which makes working with distributed, cross-user data just as simple as working with local-only data.

Predictions: The Predictions category enables AI/ML use cases on the frontend such as translating text, converting text to speech, and recognizing text, labels and faces in images.

Auth: We will extend the Auth category with social sign in with Web UI

Storage: We will extend the Storage category with the ability to track Upload and Download Progress

Escape Hatches: We will add support for ‘escape hatches’, enabling developers to more easily use the low-level generated iOS and Android AWS Mobile SDKs for additional use cases.

Contributing and Feedback

We are excited to bring these Amplify features to the Flutter community and greatly value your feedback on the developer experience working with the library. We encourage you to open any issues/feature requests on our GitHub repo or interact with us on Discord. If you have questions or suggestions regarding the design of the library or in general, please let us know more on this RFC.

Flutter and the related logo are trademarks of Google LLC. We are not endorsed by or affiliated with Google LLC.