AWS Mobile Blog

Deploy and Secure REST-based Mobile Apps with AWS Mobile Hub

The post was written by Brice Pelle, AWS Technical Account Manager.

RESTful APIs are used today to power many mobile apps. Using RESTful interfaces allows developers to decouple the frontend application from the backend systems and provides standard interoperability between the two components. Controlling access to resources can be hard to set up. This usually requires addressing authentication and authorization concerns.

In this article, I am going to look at how AWS Mobile Hub helps build a serverless mobile backend that exposes REST interfaces, and uses Amazon Cognito to help developers integrate authentication and authorization into an Ionic v2 app. I will be using a sample app, to demonstrate the implementation. The app is a simple task management app that allows access to authenticated and unauthenticated users.


Building fine-grained authorization using Amazon Cognito User Pools groups

This post was authored by Leo Drakopoulos, AWS Solutions Architect.

User authentication and authorization can be challenging when building web and mobile apps. The challenges include handling user data and passwords, token-based authentication, managing fine-grained permissions, scalability, federation, and more.

In this post, we show how to integrate authentication and authorization into an Angular web app by using AWS services. You can use Amazon Cognito to control permissions for different user groups in your app. This ensures that users have appropriate access to backend resources, determined by the group they belong to.


The Fastest Way to Analytics for Your iOS App

You just got a new customer for your mobile app. Congratulations! But be careful not to celebrate too early. Did you know that nearly 25% of customers never revisit an app after initial use? After a full month, the fall-off is nearly total. What happened?

Analytics are no longer an option for mobile developers—they’re a requirement if you want your app to succeed. Gaining and keeping mobile customers is expensive and challenging. Developers are rapidly turning to analytics to drive their customer acquisition and retention strategies.

In this blog post, we discuss why analytics are so important for acquiring and retaining mobile app customers, what type of data you should track, and how to begin. Let’s get started.

Why mobile analytics are important

Analytics play a huge role in two of the most important areas for mobile app growth and success: acquisition and retention.

Acquiring iOS customers is expensive, with an average cost of $7.52 per customer! The moment you gain that customer, retention efforts must begin. To retain customers, you need to understand and engage them. Understanding customer segments and behavior are key to defining the right customer experience.

Furthermore, analytics insights help you prioritize new features, help you decide which performance improvements to make, and allows you reach out to customers based on their usage. You can even use analytics data to reevaluate the business purpose and ROI of your app.

What analytics to track

We talked about how customer demographics (or segments) can be used and correlated with higher retention and how you can use those findings to acquire new customers.

Start by tracking customer demographics such as device type, OS, app version, and session length. Each of these metrics provides insights about your audience. Another dataset includes customer behavior trends. These help you understand each customer’s level of engagement, purchase activity, loyalty factor, and more.

How to begin tracking analytics

We talked about the importance of collecting customer demographics and behavior trends to identify and correlate retention and guide acquisition efforts for your mobile app. How can you start today?

First, engage with a cloud provider. You need infrastructure that scales and enables you to store large amounts of data for low cost. To integrate analytics, the best approach is to use an SDK from your cloud analytics provider. The SDK should be optimized for offline event storage (caching). It should store and forward events to the server when the app is connected and idle. In addition, a great SDK collects session data and all the required demographics automatically when your app is first launched. You integrate the SDK into your app and set up some optional custom events. The SDK sends raw analytics to a service endpoint that collects and aggregates your data.

Here’s how to use the AWS Mobile SDK for iOS with Amazon Pinpoint to track customer demographics and behavior today:

To enable mobile analytics for your app

  1. Sign in to the AWS Mobile Hub console at
  2. Create a Mobile Hub project.
  3. Choose Messaging & Analytics and then choose enable Analytics.

Now you are ready to integrate analytics into your app.

To collect analytics for your app

  1. Choose integrate from the left panel of the Mobile Hub console.
  2. Choose the iOS Swift tab and choose OPTION 2 for integrating the analytics SDK into your app.
  3. Download the SDK and helper code, and then follow the instructions for integrating the SDK and helper code into your existing app.

Let’s explore analytics for a sample notes app on iOS

Using a simple iOS notes sample starter app, we enabled the Messaging & Analytics feature in AWS Mobile Hub. We then followed the integration instructions to include the SDK and helper code into the app to immediately start tracking customer demographics and behavior. We also added a custom event to track the number of new notes created (see the code below). Here’s what the aggregated data collected looks like in the Amazon Pinpoint console a few minutes after the app was first launched.

[User Demographics]

[User Behavior] – custom event

*The function code is a custom event that is called when a new note is created.

In conclusion

  • Use analytics to make informed choices that help you acquire and retain mobile app customers.
  • Track both customer demographics and customer behavior trends to gain useful insights that guide you in building a compelling app experience.
  • Choose a reliable cloud service that provides a native mobile SDK and provides you with control over your own raw data. The SDK must provide methods to analyze, engage, and convert your customers based on the data you collect.

React serverless starter application with one-click AWS deployment and hosting

Serverless applications are more popular every day. Many developers want to implement completely serverless hosted websites that are functionally equivalent to traditional infrastructures. However, with serverless websites, it’s often tricky to deal with registration, sign-in, and MFA flows. It can also be difficult to manage API routing, CORS settings, endpoint authorization, and user authentication. Hooking all of these features together with a hosting solution and global CDN takes extra time for features that are standard for business applications today.

We’ve recently been blogging about building applications with React and using them in conjunction with the Hosting and Streaming AWS Mobile Hub features. Today, we are announcing a couple of additions to this solution set.

First, we’ve enhanced the Cloud Logic functionality in a Mobile Hub project so that new projects launched via Import can include a custom AWS Lambda function. The import can also configure more settings such as CORS for Amazon API Gateway or Lambda environment variables.

Second we are releasing a ReactJS starter project on GitHub to demonstrate these capabilities. The sample can be run with a single click, using the new Deploy from GitHub button capabilities of Mobile Hub. After it is deployed, you can run the sample locally with a webpack server. You can also deploy it as an Amazon S3 hosted static site with an Amazon CloudFront origin. The sample is optimized for mobile devices, which enables you to view the app from your phone or desktop browser. You can register users in the system and log user in with SMS-based MFA. After they are signed in, users can insert sample data for “BBQ Restaurants” and view all restaurants in the system. They can then navigate to see everything on the menu and place an order. The sample also demonstrates using forgotten password workflows.

In the sample, the import functionality automatically configures the following:

  • Amazon Cognito User Pools and Federated Identities
  • Amazon API Gateway, AWS Lambda, and Amazon DynamoDB
  • Cross-origin resource sharing (CORS) for the API
  • IAM roles and policy for the Lambda execution role
  • IAM roles and policy for the user roles that access API routes after authentication

You can find the sample demonstrating this functionality here. The repository describes the steps to get the sample running, and describes how to use portions of the sample in your own application and customizations. In this blog post, we dive into a few details.


To get the sample running quickly you need:


Clone the GitHub repository and use the Deploy to Mobile Hub button on the page.

After the deployment is complete, click Hosting and Streaming in the Mobile Hub console. At the bottom of the page, download the aws-exports.js file into the ./aws-mobile-react-sample/client/src/configuration folder of your cloned repo.

Use the following commands to run the application:

npm install
npm start

Walkthrough of the application

After the application is running you will see a page with a Login or SignUp Now button. Click SignUp Now to register a new user in the system.

An SMS confirmation code is sent to the phone number you provide. You must provide the phone number to complete the registration process. The confirmation code redirects you to the home screen, where you enter the username and password and then click Login.

You will recieve another confirmation code. This is the MFA code for logging in the user. Enter the code in the screen to complete the login process.

Now that you’re in the application, click Insert Restaurants to load data into the system. Behind the scenes, this invokes Amazon API Gateway, using the valid user credentials from Amazon Cognito. The API is configured to route the request to AWS Lambda, which is running Express using AWS Serverless Express. A route is configured to initialize data, which inserts sample data into Amazon DynamoDB.

Next click List Restaurants. The restaurants that were added into DynamoDB appear

Click any of the restaurants to see a menu. Place an order by clicking the Order button next to an item.

To see the current order, click Orders in the navigation bar. Two records display immediately and two other records display momentarily. This is to demonstrate persisting data in local storage for rendering versus returning a response from a network call.

You can also package and deploy the app by running:

npm run build

The build uses webpack to produce a bundle that can be uploaded to the S3 bucket created by the import. The output will be in ./aws-mobile-react-sample/client/build.

You can use the AWS CLI to upload the contents of this directory to the bucket. This process is described on GitHub. You can also use the Manage Files function in the Hosting and Streaming page of the Mobile Hub console.

After you upload the contents of the build directory, click either View from S3 or View from CloudFront to see your deployed erverless website.


The GitHub repository covers some advanced scenarios for modifying this sample or using pieces of it in your own React application. Some of these scenarios are as follows:

  • Using the registration and login components with Amazon Cognito for your application.
  • Using the REST client to make signed, authenticated requests to Amazon API Gatway.
  • Using the REST client to make unauthenticated requests to Amazon API Gateway or generic HTTP resources.
  • Modifying the Express routes in AWS Lambda to perform different operations against Amazon DynamoDB, and calling these routes from the client application.

You can also modify the import process to fit your needs and include this in your own GitHub repository with a one-click button. If you open the ./aws-mobile-react-sample/backend/import_mobilehub directory in the repository and unzip, you will find the following:

  • mobile-hub-project.yml

The is the pre-built Lambda function, which you can use on import. This must follow the Lambda deployment process described in the AWS Lambda Developer Guide. We also include these steps in the Advanced section of the repository.

If you edit mobile-hub-project.yml you’ll notice some other interesting things that are now available for you to configure with project imports.


The uploads section determines the custom AWS Lambda function that you can provide during an import. In our sample we use, which was created from the files in the ./aws-mobile-react-sample/backend/lambda directory. The YAML section should also specify the target bucket as follows:

  - !com.amazonaws.mobilehub.v0.Upload
    targetS3Bucket: deployments


In the same YAML file, you’ll notice the cloudlogic section. This contains everything you need to configure a custom AWS Lambda function and related settings as well as setting up your Amazon API Gatway API. You can configure things such as enabling CORS on the API or only allowing authenticated and authorized users access to invoke the API. This sample YAML demonstrates using Amazon Cognito to access the Amazon API Gateway API and configuring environment variables for your custom AWS Lambda function. You’ll also see controls such as runtime for your NodeJS version and handler which is the name of the file entry point for your code.

You can use ___DYNAMIC_PREFIX___-statictext in the enviornment variables configuration. This is beneficial for resources such as Amazon DynamoDB tables, which are generated at the time of import, Mobile Hub performs the appropriate substitutions after resource creation.

The YAML section should look like the following:

  cloudlogic: !com.amazonaws.mobilehub.v0.CloudLogic
      ReactSample: !com.amazonaws.mobilehub.v0.API
          name: ReactSample
          requires-signin: true
          /items: !com.amazonaws.mobilehub.v0.Function
            name: ReactSample
            codeFilename: uploads/
            handler: lambda.handler
            enableCORS: true
            runtime: nodejs6.10
              MENU_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_menu_item
              ORDERS_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_orders
              RESTAURANTS_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_restaurants
          "/items/{proxy+}": !com.amazonaws.mobilehub.v0.Function
            name: ReactSample
            codeFilename: uploads/
            handler: lambda.handler
            enableCORS: true
            runtime: nodejs6.10
              MENU_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_menu_item
              ORDERS_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_orders
              RESTAURANTS_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_restaurants


The Mobile Hub import process also prepopulates some Environment Variables in the Lambda configuration:


As a usage example, you could re-write the Lambda code in the starter application to reference these like so:

const MENU_TABLE_NAME = `${process.env.MOBILE_HUB_DYNAMIC_PREFIX}-bbq_menu_item`;
const ORDERS_TABLE_NAME = `${process.env.MOBILE_HUB_DYNAMIC_PREFIX}-bbq_orders`;
const RESTAURANTS_TABLE_NAME = `${process.env.MOBILE_HUB_DYNAMIC_PREFIX}-bbq_restaurants `;

You could also use these prepopulated variables for other utility purposes.

Wrapping up

We’re excited to bring you these capabilities. We hope that they accelerate your next serverless website or React project using AWS. Let us know in the GitHub issues section of the repository if you have any feedback or requests.

Deploying an EmberJS mobile web application with Mobile Hub

This post was authored by Michael Labieniec, AWS Sr. Solutions Architect.

AWS Serverless Architecture

Ember.js is a popular open source JavaScript framework for developing rich, dynamic web applications. It supports dependancy injection model and has been a is a stable contender in the JavaScript community. Ember.js also ships with its own CLI which supports building, testing, and deploying your applications. The Ember CLI supports installing plugins and the bundling of those plugins within your application, it has a built in web server to serve your application locally.

AWS Mobile Hub is an AWS service that guides you through feature selection and configuration, it automatically provisions the AWS services required. Mobile Hub generates working code that helps you integrate the AWS SDK for JavaScript with your application in minutes. When using Mobile Hub to develop JavaScript-based applications, JavaScript configuration files as well as a sample web application are generated for you, and placed in your Amazon S3 bucket. These configuration files can then be copied directly to your application environment for use. The files can be continuously updated when your AWS environment changes via Mobile Hub. This is useful for developing JavaScript web applications because your AWS configuration can be dynamically updated by Mobile Hub and your application can immediately realize and support those updates when hosted in Amazon S3.

Mobile Hub will copy a new aws-config.js and aws-exports.js to the Amazon S3 bucket associated with your application after you update your configuration. In order to utilize these in your local development environment, you need to download them from your S3 bucket. The files will be copied to the root of the S3 bucket, which may require you to copy them elsewhere for your application to properly include them.

Amazon Cognito lets you add user sign-up and sign-in to your mobile and web applications. This sample application uses Cognito User Pools for user management and storage, and Amazon Cognito Federated Identities for authentication the user pool. The application then uses Amazon DynamoDB directly through the AWS SDK for JavaScript. The sample application uses a custom Ember.js Adapter to abstract the API logic and allow utilization of Ember.js Models.

First, clone the repository and install the dependencies:

git clone
cd aws-mobilehub-ember && npm install

Then, click the following button to import the file and create the AWS back-end:

Alternatively you can download the .zip file from the GitHub repository and from the Mobile Hub console click Import your project and drag and drop the .zip file to create a new project.

After the import is complete the AWS environment is ready. Click Hosting and Streaming, and then click Download aws-config.js file. Copy the aws-config.js file to the ./vendor/aws-config.js directory of your application.

You can also download the file with the AWS CLI. You first need to know the Amazon S3 hosting bucket. You can see the bucket name by going to Resources from within you Mobile Hub project. Then from within the root directory of your application project run:

aws s3 cp s3://your-hosting-bucket/aws-config.js ./vendor/aws-config.js

If you don’t already have the Ember CLI installed run the following:

npm install -g ember-cli

Now that the aws-config.js file is copied to your vendor directory, run the following:

ember serve

Your application should now be available at localhost:4200. If you ever change your AWS Mobile Hub configuration, simply cp the configuration file again and deploy.

To retrieve the generated S3 bucket name for the cli commands, navigate to your project in the Mobile Hub console, click Hosting and Streaming, and then click Manage Files. Note the bucket name at the top of the screen.

To deploy your web application to Amazon S3, run the following:

ember build 
aws s3 cp --recursive ./dist s3://your-s3-hosting-bucket/

Your web application is now available at the web hosting URL of the Amazon S3 bucket that Mobile Hub generated. To view your application:

  1. Goto Mobile Hub and click Hosting and Streaming
  2. Click View from S3

After about a minute, the file changes you pushed propagate to the CloudFront distribution. You can click View from CloudFront and browse the site from a CDN for faster performance. You can force this refresh to happen immediately from the Hosting and Streaming page:

  1. Click Edit your CDN distribution
  2. Click the Invalidations tab
  3. Select Create Invalidation and enter an asterisk (*) to refresh all the content

After the process completes, click View from CloudFront in the Hosting and Streaming section of Mobile Hub.

Making changes

We detail the application architecture at the end of this blog post. You can change parts of the application to meet your needs. Each time you deploy the application you must build and copy to Amazon S3, as follows:

ember build
aws s3 cp --recursive ./dist s3://your-s3-hosting-bucket/

Then either wait for a CloudFront distribution refresh or force one with an invalidation.

Walking through the sample

The Ember sample is a TODO or “notes” application. It walks through functionality for registering user accounts into your application (including email confirmation), login and logout functionality, session information and saving notes to a database. To demonstrate, first select Create User to register a new user account in the system. Enter the following:

  1. Unique username
  2. Complex password
  3. Valid email address

This process registers a user in the system with Amazon Cognito User Pools. A registration confirmation code is sent to the email address. Type that code in the page and select Confirm Registration at the bottom. The workflow for this sample allows you to immediately press Login with the previously entered credentials to access the application.

In the main page create a new note by clicking the plus sign (+) in the lower right corner. Type a title for the note and some content. Click Save Note, your data is written to Amazon DynamoDB. These notes are secured where only the users who create them can read or edit them after logging in.

Select the user’s name in the upper right corner of the page. Here you see information about the user session, such as JWT token details from Amazon Cognito User Pools. This is a great place to store user-specific attributes that can be read-only or editable by the user. Click User Attributes on the left side to view your email address.

Application Anatomy

Now that the sample application is up and running we dive a little deeper and explain the structure of an Ember application. You can incorporate pieces of the sample into your own projects.

There are two types of initializers in Ember: application initializers and application instance initializers.

Application initializers while your application boots and have no access to internal services. The application initializer performs a dependency injection process to ensure that everything your application needs is setup before loading UI or user state. This is also great for security control and separation of concerns in your application architecture.

Application instance initializers run while the application instance itself loads. This provides a way to configure the initial state of the application and inject values into application services. For example you can customize the UI based on a theme for users and control state.

Application Initializers

This application uses both types of initializers. The initializers allow us to initialize the AWS SDK for JavaScript before the application instance loads. The instance initializer allows us to inject values into services. We also use the deferReadiness and advanceReadiness in the application initializer to defer loading of the application until we have temporary credentials for making AWS API calls. The main application initializer is located in the app/initializers directory, as follows:


To generate an initilizer runember g initializer myInitializer. This creates a new initializer .js file named app/initializers/myInitializer.js. It also create a unit test in tests/unit/initializers/myInitializer.js.

The AWS initializer instantiates the AWS SDK using the variables that are instantiated in the configuration file that Mobile Hub generated. This file was copied from your Amazon S3 bucket. Then, the initializer checks if there is a current session with Amazon Cognito User Pools. It retrieves temporary SDK credentials. The initializer uses these credentials to make AWS API calls with the SDK. The initializer then registers values for the application to use, and finally advanceReadiness to continue loading the application instance.

The initializer determines if there is a logged in user with the Amazon Cognito Identity SDK (included in ./vendor/amazon-cognito). If a session exists, register the session credentials and JWT tokens on the application instance. These are injected by the instance initializer.

Application Instance Initializers

The instance initializer is located in the instance-initializers directory, as shown next:


When the instance initializer runs, it has access to application services, as well as access to any values we previously registered within the application initializer.

You can generate instance-initializers with the ember-cli using ember g instance-initializer myInstanceInitializer. This generates a myInstanceInitializer.js in the instance-initializers folder. It also generates a unit test in test/unit/instance-initializers.

The auth instance initializer first retrieves the values registered in the application initializer, as well as the service we have created (app/services/cognito.js). Ember services are referenced using the prefix “service:”. The application-registered values that we registered in the initializer are completely custom (for example “auth:session”). It then injects those dependencies into the applicable service within our instantiated application instance: in this case, our custom cognito service.

Application Components

Within this application we use a service, model, adapter, and serializer to abstract the AWS logic away from the presentation level logic. This allows us to work with data using ember models, while the application adapter and serializer hold AWS-specific back-end logic. This architecture allows us to potentially swap adapters that communicate with different back-ends, or to even load and serialize different types of data (for example JSON vs. XML responses). The serializer takes whatever is retrieved via the adapter and serializes it to a uniform format (based on the extended ember class) for our routes and components to use.

Models, Adapters, and Serializers

The note adapter in this application is specifically tied to the note model, and note serializer. Ember uses this file-level naming convention to determine which components work together. For example, the note model utilizes the note adapter and serializer if the similarly named .js files are found in app/serializers or app/adapters. You can also define an “application” adapter and serializer which serves as a catch-all for any model actions.

You can generate a model by running ember g model myModel, which does not generate an adapter or serializer. You can generate these with ember g serializer|adapter. As long as you name them appropriately, they will are used. Otherwise, the model uses an application adapter or serializer if you generated one.

Data is initially requested via the note route. This route provides the result from the adapters call, serialized, to the Ember component, which in this case is directly used within the view. This model.notes dataset is then sent into the ui-note-list component for use within the view component.

Components and Controllers

Components are custom elements that align with the W3C Custom Elements spec and contain de-coupled view logic.

Components can reference and call methods on the higher level component or controller that instantiated the component. This abstracts away the model or data level logic, making the component more dynamic and re-usable. Components should never work with models or data. They should work with specific view logic and the data that is provided to them, allowing the components to be more de-coupled and re-usable. Components can also work with services directly.

Components can be generated via the ember-cli ember g component myComponent. This creates an app/components/my-component.js logic file, and an app/templates/components/my-component.hbs view template. Since Ember components adhere to the W3C Custom Elements spec, they require a “-” in their name.

To learn more about developing with Ember, see Guides and Tutorials on the Ember website.

Wrapping up

Using the Hosting and Streaming features of Mobile Hub is a great way to quickly provision a fully functioning back-end for your mobile web application. The application includes end-to-end functionality, including user life-cycle and application state. Using the provided sample should help you get started with building an Ember application. You can make changes to this application and get your site running quickly. You can also use the sample and the Deploy from GitHub Button, like this repository shows, to fork this application and create your own version. Others can use your version to quickly spin up a fully functioning back-ends.

Questions or Comments?
Reach out to us on the AWS Mobile Development Forum.

Source Code and Issues on GitHub

Take Your Chatbot Mobile!

With Amazon Lex, any developer can quickly and easily create a chatbot. With AWS Mobile Hub, the same developer can just as easily integrate the bot into a mobile app.

Want to take your bot mobile? Use the Mobile Hub conversational bots feature to create your own mobile bot or import an existing bot into your mobile app. You can build, test, and publish your mobile bot in minutes. No deep learning expertise needed.

How does integration work? Integrate your bot into a fully native mobile app by using a sample bot template or by importing an existing Amazon Lex chatbot into Mobile Hub. Mobile Hub generates a fully functional mobile iOS or Android app, integrated with your bot. The sample mobile app provides the option to interact with your bot with voice or text, and includes built-in authentication provided by Amazon Cognito.

How do I do it?
Here’s how simple it is:

  1. Use Amazon Lex to build a bot or choose from one of the sample bots in Mobile Hub.
  2. Import your bot into Mobile Hub using the conversational bots feature.
  3. Download the generated iOS/Android project code.
  4. Launch your mobile app and start a conversation!

Want to see how others have done it?

The Kelley Blue Book team created their voice-enabled mobile application using Amazon Lex and Mobile Hub. Their bot allows users to interact with their vehicle API using natural spoken language. A simple inquiry like, “Kelley Blue Book, can you tell me the trade-in value for my 2012 Honda Civic?” gets expert car advice from an industry-leading automotive company.

To learn more about The Kelley Blue Book Bot and building your own mobile chatbot, see the post on the AWS AI blog.

We can’t wait to see what you can build with AWS Mobile Hub and Amazon Lex!

Testing Mobile Apps: A Primer

Why should you test your mobile app?  A recent study showed that almost a quarter of users only use a mobile app once, and a shocking 95% abandon an app within the first month.  Some of the reasons that users abandon an app are due to content and engagement.  The biggest non-content reasons for abandonment are application crashes and security concerns.  No one can prevent all application crashes.  The mobile ecosystem is too broad and unpredictable to provide a 100% guarantee.  However, testing ensures that your mobile app has been stressed on as many devices as possible , which enables you to identify and fix bugs early.

Types of mobile testing

There are seven types of scenarios that you should consider when testing a client-server application such as a mobile app:

  • Unit testing
  • UI testing
  • Fuzz testing
  • Performance testing
  • End-to-end testing
  • Pre-production testing
  • Canary (post-production) testing

Tests are organized into test suites – sets of tests that together test the entire functionality of your app.  Let’s look at each of these types.

Unit testing

Unit testing tests individual parts of your code for correctness, usually using an automated test suite.  A good unit test assures you that the functionality that you are expecting out of the unit (your code; usually a single method) is correct.  A good unit test is:

  • Repeatable – you can run it several times and it produces the same result.
  • Fast – you don’t want it to interrupt the flow of your work.
  • Readable – you can understand what the test is doing.
  • Independent – you can run a single test from a suite.
  • Comprehensive – you have enough tests to test all the main cases and corner cases of inputs and cover all code paths.

A good unit test suite augments the developer documentation for your app. This helps new developers come up to speed by describing the functionality of specific methods.  When coupled with good code coverage, a unit test acts as a safeguard against regressions.  Unit tests are important for anything that does not produce a UI.  For example, consider a Notes app that has a set of notes stored in a SQLite database on a mobile device. For this app, there is a class that accesses the notes and a set of classes that implement the UI.  The class that accesses the notes has unit tests.

Each platform has its own unit testing framework:

Each of these frameworks supports all of the features you need to start testing, including support for async functionality (a common pattern in mobile apps).   Each testing framework has its own appearance, but in essence all testing frameworks operate the same.  You specify some inputs, call the method to test, and then verify that the output is what you expect it to be.

UI testing

UI testing takes a flow that the user might follow and ensures it produces the right output.  It can be done on real devices or on emulators and simulators.  Given the same state (including backing stores and starting point), the UI test always produces the same output.  A UI test can be considered similar to a unit test. The input to the test is the user clicks and the output of the test is the screen.  UI testing is more closely associated with the device than with the platform language.  There is a preferred testing framework and each framework has a test recorder. This enables you to record a UI flow on one device and then replay the test on many other devices.  The test recorder allows you to get productive quickly:

In addition, there are cross-platform UI test frameworks to consider, primarily Appium and Calabash.  With Appium, you can choose a language. This is useful if you are writing Ionic or React Native apps because you can use JavaScript as the testing language.  Calabash requires that the tests are written in Ruby.  Neither of these frameworks provide a recorder to aid in writing tests.  Both frameworks are open source projects.

Finally, AWS Device Farm has a feature called Explorer for Android apps.  This feature investigates your UI and finds things to interact with.  When it finds a control, it interacts with the control.  This feature works with login screens, allowing you to validate authenticated sessions as well.

Ionic and React Native perform UI testing against compiled code, so your UI tests should not include Ionic or React Native code.  Instead, you are testing how the app acts on a device.

Fuzz testing

Unit tests and UI tests are used to ensure that the expected output happens when the expected input is used.  However, apps are used by humans and humans don’t always do the expected thing.  For that case, you can introduce a random stream of events into your app and see what happens.  This is known as monkey testing or fuzz testing. It’s a stress test that simulates what happens when the user randomly presses the screen, for example.  This is similar to a UI test.  However, you don’t need to write any tests since random events are created.

It is also interesting to record a fuzz test run.  It can be replayed later to reproduce any issue found, verify that the issue was fixed, and to scale testing across more devices.  Fuzz testing takes off when you take testing to the cloud with AWS Device Farm, allowing you to test on many more devices than you may have access to.

Performance testing

Gather performance metrics while running the UI and fuzz tests to ensure that your application does not take up significant resources on the device.  Such performance metrics include:

  • Battery drain and energy usage.
  • Appropriate usage of the GPS and other features that drain battery.
  • Network bandwidth usage.
  • Memory usage.

This data can be gathered during development using a profiling tool such as the Android Monitor (built into Android Studio) or Instruments (built into XCode).  During this process, you can also use network shaping, which simulates lower bandwidth network connections (for example, 3G connections) or spotty Wi-Fi connections.  This enables you to experience adverse network conditions as your users would and ensure an appropriate user experience.  If you are developing a mobile game, you can also measure the FPS (frames per second) for your mobile game when the device is stressed (low memory or restricted network capabilities).

For performance testing during the test phase (and beyond), use application performance monitoring (APM) tools such as New Relic Mobile or Splunk MINT.

Integration (end-to-end) testing

After you test your mobile app in isolation, you test it with a mobile backend. This is generally known as integration testing or end-to-end testing.  Take the same UI and fuzz testing that we already described, and then recompile your code with the live cloud backend.  Many organizations produce a separate test environment for this purpose.

If you are upgrading the mobile app (rather than releasing a new app) and the upgrade involves an upgrade to the backend resources – the database schema or API responses – then you also should test the upgrade scenarios during integration testing.  Users do not upgrade their mobile apps immediately, so multiple versions of your app will use the same cloud backend resources (even if only the database is affected).

If you are using a third-party cloud service (for example, a Weather API), then make sure you check their rules for throttling.  Test failures can result if the third-party cloud service detects you are making too many API calls.

Pre-launch or pre-submission testing

You are just about to launch your app to the public.  You’ve done all the appropriate testing on the latest devices and OS versions.  Run the UI and fuzz tests on as wide a pool of devices as you possibly can.  There is one final test before submitting your app to the app store.  You want to test your app on as large a community of devices and OS combinations as you possibly can.

An enterprise usually has the luxury of dictating a support matrix of devices. If you are producing a mobile app for the general public, then the situation is a little more complex.  OpenSignal estimates that there are over 24,000 distinct Android devices in the world. Over 18,000 of these were used in the last year.  The statistics from Google indicate that API level 19 (which is a few years old at this point) has only reached 73% of consumers. The iOS device types are a little more limited – there are only a handful of models, and iOS devices tend to be kept up to date.  That’s still numerous device / OS combinations.

One option is to maintain a device farm of your own, buying one of each device.  However, that is expensive to buy and maintain. A better option is to rent the devices you need for the pre-production run and let someone else worry about maintaining the latest device and OS versions. AWS Device Farm helps with this problem as well, running your UI and fuzz tests across a wide variety of devices and charging only for what you use.

Canary (post-production) testing

After your app is in production, use a canary test to ensure that the mobile app and the backend are running harmoniously. A canary test is a set of UI tests that run using the same mobile app that you distributed to your users and using the same (production) services on the backend.

You can generate a (different, smaller) test suite for an individual (canary) user and run this test suite on AWS Device Farm on a schedule to implement canary testing.

Best practices in testing

You don’t need to run all tests all the time.  The following are some best practices:

  • Architect your application so that the mobile application and backend can be tested independently.  Compile your app with “stub” methods that simulate the cloud services.  Also, try mock cloud services with frameworks like Mockito (Android) or Cuckoo (Swift).
  • All changes to the code base of your mobile app or backend should include appropriate unit tests or UI tests to check the new functionality.
  • Run unit tests with every build and UI tests on an emulator or simulator before checking in your code change.
  • Run a complete set of UI and fuzz tests on a pre-defined set of the most popular devices for your users on a regular basis. It is ideal to do this as part of a continuous integration pipeline (for example, using Jenkins). At minimum, you should run these tests on a nightly basis.  Monitor for application crashes and test failures.
  • Run your UI tests on as many devices as possible at intervals throughout the development process. At minimum, run a full set of tests on as many devices as possible before release.  Any test failures or application crashes should generate bugs to be fixed by the engineers.
  • Include enough information in your bugs to reproduce the failure. Include the test case, device and OS combination, whether the test was against the cloud services or the stubs, and video or screen captures of the test failure.
  • Analyze the test results.  A single test failure is useful.  Knowing that the same error or crash occurred on a set of devices with a common characteristic is more useful to the developers who need to diagnose the problem.

AWS Device Farm is a mobile app testing service that lets you test and interact with your Android, iOS, and web apps on many devices at once. It enables you to capture video, screenshots, logs, and performance data to pinpoint and fix issues before shipping your app.  You can use it to automate a large portion of the suggested mobile app testing capabilities described in this article.

With these best practices, you are on your way to producing a quality product that can be enjoyed by the maximum number of users.

Integrate the AWS SDK for JavaScript into a React App

In our last blog post, I showed how to create a React app using the create-react-app tool provided by Facebook, and then deploy the app to a content delivery network driven by AWS Mobile Hub, Amazon S3, and Amazon CloudFront. This enables you to produce dynamic single page applications (SPAs) and serve them to a global audience.

Very few web apps are static web sites.  Ideally, you also deploy a serverless backend that includes identity, database, storage, and custom APIs that provide the dynamic data for your SPA. AWS provides this kind of serverless backend. You can compose this backend by using the AWS Mobile Hub console. You still need to integrate the AWS SDK for JavaScript into your SPA. In this post, we walk through that integration.

Add the AWS SDK for JavaScript to your project

The SDK is distributed via the npm package manager. To install the SDK into your project, use the following command:

npm install –save aws-sdk

This downloads the SDK and adds an entry into the package.json file so that the SDK is downloaded automatically when it is needed. In addition, any dependencies for the SDK are downloaded and included in your project.

Download the AWS configuration for your project

In the last article, we showed you how to create an AWS Mobile Hub project and turn on the Hosting and Streaming service. This also generates two files in the Amazon S3 bucket that is created:

  • aws-config.js is used by browser sessions to configure the SDK.
  • aws-exports.js is used by SPA applications that are packed (by Webpack, Browserify, or similar tools) to configure the SDK.

You need the aws-exports.js file for the React app. You can download this file from the Amazon S3 bucket using either the AWS Mobile Hub console or the AWS CLI. To download via the CLI, use the following:

aws s3 cp s3://bucket/aws-exports.js ./src/aws-exports.js

From the AWS Mobile Hub console:

  1. Sign in to the AWS Mobile Hub console.
  2. Choose your project.
  3. Choose Hosting and Streaming.
  4. Click Download aws-exports.js file.

You can (and should) do this before every build. I have included the following in my package.json:

	"scripts": {
		"prebuild": "aws s3 cp s3://${S3BUCKET}/aws-exports.js ./src/aws-exports.js",
		"build": "react-scripts build",
		"deploy": "aws s3 cp ./build s3://${S3BUCKET}/ --recursive",
		"start": "react-scripts start",
		"test": "react-scripts test –env=jsdom",
		"eject": "react-scripts eject"

Set the S3BUCKET environment variable and build the React app as follows:

# For MacOS or Linux
export S3BUCKET=reacttestapp-hosting-mobilehub-1234567890
# For Windows cmd
# set S3BUCKET=reacttestapp-hosting-mobilehub-1234567890
# For Windows PowerShell
# $env:S3BUCKET="reacttestapp-hosting-mobilehub-1234567890"

# Now run the build
npm run build

Integrate the SDK into your app

In each SPA, there is an entry point. The entry point for all apps created by create-react-app is the src/App.js file. The create-react-app tool uses ES2015 modules.  This means we can use the import keyword to bring in the aws-exports.js file:

 * Import the SDK and Project Configuration
import AWS from 'aws-sdk';
import awsmobile from './aws-exports';

 * Configure the SDK to use anonymous identity 
  region: awsmobile.aws_cognito_region,
  credentials: new AWS.CognitoIdentityCredentials({
    IdentityPoolId: awsmobile.aws_cognito_identity_pool_id

In this snippet, we import both the SDK and the configuration of the backend, and then automatically create identity credentials for Amazon Cognito based on the configuration. We can also use this to instantiate an Amazon DynamoDB connection or call an Amazon API Gateway REST endpoint using the SDK.

What’s in the aws-exports.js

The aws-exports.js file is a standard JavaScript file that is maintained by AWS Mobile Hub on your behalf. It changes when you add, remove, or edit features within AWS Mobile Hub. An example from one of my apps is below:

// WARNING: DO NOT EDIT. This file is Auto-Generated by AWS Mobile Hub. It will be overwritten.

// Copyright 2017, Inc. or its affiliates (Amazon). All Rights Reserved.
// Code generated by AWS Mobile Hub. Amazon gives unlimited permission to
// copy, distribute and modify it.

// AWS Mobile Hub Project Constants
const awsmobile = {
aws_app_analytics : 'enable',
aws_cognito_identity_pool_id : 'us-east-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
aws_cognito_region : 'us-east-1',
aws_content_delivery : 'enable',
aws_content_delivery_bucket : 'XXXXXX-hosting-mobilehub-1234567890',
aws_content_delivery_bucket_region : 'us-east-1',
aws_content_delivery_cloudfront : 'enable',
aws_content_delivery_cloudfront_domain : '',
aws_mobile_analytics_app_id : 'XXXXXXXXXXXXXXXXXXXXXXX',
aws_project_name : 'XXXXXX’,
aws_project_region : 'us-east-1',
aws_resource_name_prefix : 'XXXXXX-mobilehub-1234567890’,

export default awsmobile;
var AWS = require('aws-sdk');
AWS.config.region = awsmobile.aws_project_region;
AWS.config.update({customUserAgent: 'MobileHub v0.1'});

This project has the following enabled:

  • Analytics (from the Messaging and Analytics feature)
  • Hosting and Streaming

You can see the appropriate IDs are available through constants that are then exported as a module. You should never edit this file directly. Instead, change the features within your AWS Mobile Hub project and then copy the file to your source code control again.

Best Practices

We consider the following best practices for integrating the SDK:

  1. Always use the latest version of the SDK.
  2. Add the src/aws-exports.js file to your .gitignore (or similar) file. Do not check this file into your source code repository.
  3. Copy the aws-exports.js file from your AWS Mobile Hub project during the build phase of your app.

Now that you know how to integrate the SDK into your app, you can start using the AWS SDK for JavaScript to access your AWS services. In future articles, we will explore adding AWS service access to your React app. Until then, please see the AWS SDK for JavaScript Developer Guide for more details.

Automated Device Testing with AWS Device Farm and Jenkins

A strong indicator of quality of an app is its ability to run on multiple devices of different make, model, and manufacturer consistently and predictably. Incremental development models are at the core of every mobile app development team. Often a seemingly benign feature can be disruptive to the overall user experience and functioning of the app if not thoroughly tested. How do you ensure that every code check-in triggers tests for your mobile app against numerous devices and provides detailed analysis of the results?

Continuous integration (CI) systems have been around for a long time and are now at the core of all DevOps workflows. They integrate build, test, and distribution into one workflow. Many systems to implement CI exist, including cloud solutions like AWS CodePipeline and on-premises solutions like Jenkins. Jenkins is an open source CI solution that is easy to install and portable across all major platforms. It has more than 1000 plugins that integrate with build, test, and distribution components.  This makes Jenkins a popular choice among teams looking for a CI tool for a new project.

AWS Device Farm is an app testing service. You can use it to test and interact with your Android, iOS, and web apps on physical phones and tablets that are hosted by AWS. You can use Device Farm for automated testing with a variety of available testing frameworks. You can also use it for manual testing through a remote session.

Today, AWS Device Farm announced the availability of a Jenkins plugin for AWS Device Farm.  The Jenkins plugin enables you to integrate device testing into your CI workflow.

Prepare your AWS account so that Jenkins can access Device Farm resources:

  1. Sign in to the IAM console.
  2. Create or modify an IAM policy so that your Jenkins instance has access to AWS Device Farm.
  3. Create a user for your Jenkins master (with programmatic access) and assign the user to the IAM policy you just created.
  4. Note the access key ID and secret access key. You need them later.

Add the Jenkins plugin to your Jenkins master:

  1. Sign in to your Jenkins web UI.
  2. Click Manage Jenkins > Manage Plugins on the left side of the screen.
  3. Click the Available tab.
  4. Type aws-device-farm in the search box.
  5. Click Install without restart.
  6. After the installation is complete, click Manage Jenkins > Configure System.
  7. Scroll to the AWS Device Farm header.
  8. Paste the access key ID and secret access key into the appropriate boxes.
  9. Click Save.

You can also use the Jenkins CLI to manage plugins.  Now that the Jenkins plugin for AWS Device Farm is available on your Jenkins master, you can use it in a workflow:

  1. Select the project for which you want to set up the plugin.
  2. Add a post-build step: Run Tests on AWS Device Farm.
  3. Configure any options you want for the run. At minimum, select the UI tests that you want to run and the devices you want to run those tests on.
  4. Save the changes for the project.

AWS Device Farm supports major testing frameworks such as Espresso, XCTest UI, Appium, and Calabash.

After a build and test flow is complete, you can see the results of the tests:

Integrating AWS Device Farm into your automated build pipeline enables you to test your mobile applications on more devices, producing a better quality mobile app.  As always, we want to hear from you.  If you have suggestions or issues, let us know on the AWS Forums.

Deploy a React App to S3 and CloudFront with AWS Mobile Hub

Single page applications (SPAs) are now ubiquitous. Every web developer needs to understand how to build them and how to deploy them to a web hosting facility of their choice. In this article, I am going to look at what it takes to create and build a basic React app and deploy it globally to the AWS Cloud.

Before you start, you need to create a suitable cloud environment for your app. This is shown in the following architectural diagram.

All users of your app will load the single page application resources (which are all static resources) from Amazon CloudFront, which provides a global set of edge caching services. CloudFront is a caching facility –the resources it caches are from an Amazon S3 bucket. This ensures that the application is provided securely and efficiently across the globe. Amazon Route 53 provides DNS services so your service has the right name.

Prepare your development workstation

To create and deploy React applications to AWS, you need the following:

After you install and configure the AWS CLI, make sure that you have access to your AWS account via the CLI before continuing.

Create the cloud backend

Use AWS Mobile Hub to create this architecture.

  1. Sign in to the AWS Mobile Hub console.
  2. Create a project.
  3. Click Hosting and Streaming.
  4. Check the box to acknowledge the security implications, and then click Enable.

Ensure you read about the security implications of the Hosting and Streaming feature. The service creates an Amazon S3 bucket and an Amazon CloudFront distribution for you. Make a note of the Amazon S3 bucket; you need this later.

(Optional) Create a domain name for your app

The default name for your app is a little cryptic. In the picture above, you can see the URL in the CloudFront section. Amazon Route 53 can be used to give your application a more friendly URL. For details on how to accomplish this, see the Amazon Route 53 Developer Guide.

Create a React application

There are many ways to create a React application. You can integrate the components yourself, use a Yeoman generator, or use one of the many templates available. My favorite mechanism is to use create-react-app. To install create-react-app, type the following at the command line:

npm install -g create-react-app

After you install the tool, run create-react-app on the command line. Change directory to a working directory and type the following:

create-react-app test-app
cd test-app
npm install
npm start

This starts the application on your local machine. A browser starts and your application loads. Changes to the source code are then reflected in the browser. For more information on writing a React app, see the React tutorial and documentation. This is just the starting point and a great place to begin your exploration of React.

Deploy the React application to your AWS project

Deploying to your AWS project is a two-step process. First, build the deployable artifacts for your project by running the following command:

npm run build

Next, copy the deployable artifacts to your S3 bucket by running the following command:

aws s3 cp build s3://<your-s3-bucket-name> --recursive

Replace <your-s3-bucket-name> with the name of your S3 bucket.  You can add this command to the scripts section of the package.json file.  For example, the scripts section for my package.json looks like this:

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "predeploy": "react-scripts build",
    "deploy": "aws cp build s3://my-s3-bucket --recursive",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"

Only users who have access to the S3 bucket can run this script.  The AWS CLI credentials are separate from your application code.  However, you can place the S3 bucket name in an environment variable and use the environment variable instead of the specific name in your package.json file.  This ensures that your package.json file does not contain specific references to your AWS resources and that the project can be shared between multiple developers.

After the process is complete, you can browse to your S3 bucket to see your app deployed.   By default, your files are available on the CloudFront edge cache servers within an hour.  If you have a production app, you can also invalidate the contents of the CloudFront edge cache servers.   The URL of the CloudFront edge cache servers is displayed on the Hosting and Streaming feature page in AWS Mobile Hub.

The CloudFront CLI is currently in preview. You can enable it by running the following command:

aws configure set preview.cloudfront true

After you configure the preview feature, list the distributions.  On macOS, you can run the following:

aws cloudfront list-distributions | grep d21o

Replace d21o with enough of the URL for your CloudFront distribution to uniquely identify it.  I don’t have that many CloudFront distributions, so using the first few characters is enough to limit the output to just 1 line:

The highlighted text is the distribution ID associated with the URL.  I can create an invalidation as follows:

aws cloudfront create-invalidation --distribution-id <distribution-id> --paths /\*

I need to quote the wildcard character.  If I do not properly quote the *, the shell expands it to all the files in the directory.  This is definitely not what you want.  You can monitor the invalidation by running the following command:

aws cloudfront list-invalidations --distribution-id <distribution-id>

Best Practices

When working with any architecture, there are inevitably some best practices to discuss.  Content delivery networks are no different.  The best practice that you should definitely follow is to ensure you version each file.  The easiest way to do this is to use a task runner automation tool (broccoli, grunt, or gulp) for the distribution.  Use the version from the package.json file as part of the directory so that your build directory is copied to a new directory each time it is built.  When you deploy, you can adjust the version that is distributed to your end users by running the following command:

aws cloudfront update-distribution --id <distribution-id> --default-root-object 0.0.2/index.html

For example, if you are using gulp and have a Gulpfile.js, you can include the following task:

const gulp = require('gulp');
const exec = require('child_process').exec;
const version = require('./package.json').version;

// Make sure you assign your distribution ID here
const distributionid = '<your-distribution-id>'
gulp.task('update-cloudfront', (cb) => {
    const cmd = 'aws cloudfront update-distribution';
    exec(`${cmd} --id ${distributionid} --default-root-object ${version}/index.html`, cb);

Call the update-cloudfront task as the last task in the deployment pipeline to do the adjustment.  You can get the distribution ID programatically from a file.

There are many plugins for the task runners to handle AWS resources.  These can be used as an aid to produce an automated workflow for deploying from your web development workflow.

Wrap up

Now that you have a React app running within the AWS Cloud, you can use AWS Cloud features within your app.  In future blog posts, I’ll describe how to use AWS Cloud features in your React application.