Category: AWS Mobile


Announcing: React Native Starter Project with One-Click AWS Deployment and Serverless Infrastructure

React Native as a mobile development platform continues to grow in popularity. AWS has invested more in this area over the past year, and has been participating in React Native community events. Many developers want to enrich applications that they built using React Native with features like database access and content storage (images, videos, etc.), while protecting these resources with strong security mechanisms. Adding functionality such as user registration, sign-in, and MFA flows can be challenging to do in a cost effective and scalable manner.

Today, we’re announcing a new React Native starter project which has been open sourced on GitHub to help customers quickly add these features using AWS services. The project contains a starter application that can be run with a single click, using the Deploy from GitHub button capabilities of AWS Mobile Hub. After deployment finishes, the starter can be run locally using npm or yarn on either iOS or Android. The project demonstrates user sign-up and sign-in flows along with MFA as a “Pet Tracker” application, allowing you to upload pictures of your pets along with some data (name, age, breed, and gender). The pictures are stored in an S3 bucket. The bucket can only be accessed by the user. Similarly, the records corresponding to these pictures are stored in an Amazon DynamoDB table on a per-user basis as well. This is protected by a serverless infrastructure that uses Amazon API Gateway and AWS Lambda.

In addition to the starter application, which you can modify to fit your needs, the project contains several Higher Order Components (HOCs) that you can use in your application. For instance, there is a WithAuth HOC that you can use to add just the sign-up, sign-in, and MFA portions of the project to your application. Similarly, there are HOCs for secure API and storage access as well.

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

  • Amazon Cognito User Pools and Federated Identities
  • Amazon API Gateway, AWS Lambda, and Amazon DynamoDB
  • Amazon S3, including bucket policies and folder structures for private and public content
  • IAM roles and policy for the Lambda execution role
  • IAM roles and policy for the user roles that access API routes and S3 buckets after authentication

Prerequisites

To get the starter running quickly you need the following:

  • AWS account
  • NodeJS with NPM
  • React Native CLI
    • npm install -g react-native-cli
  • (optional) AWS CLI

You can find the starter project demonstrating this functionality on GitHub. The repository describes the steps to get everything running and information about how to incorporate HOCs into your own application. In this blog post, we dive into some extra details.

Installation

Clone the GitHub repository.

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-native-starter/client folder of the cloned repo.

Use the following commands to run the application:

cd ../aws-mobile-react-native-starter/client
npm install
npm run ios #npm run android

Walkthrough of the application

After the application is running, you can see the SIGN IN screen. If this is your first time running the application, choose the SIGN UP tab in the lower right and complete the process with a username, password, email address, and valid phone number.

You will receive a confirmation code for signing up through SMS; enter the code in the prompt.

Navigate back to the main sign-up screen with your new user name and password. You’ll get another SMS verification code, this time as part of the MFA process. After signing in, you will see a blank screen. Choose plus (+) in the lower right and either take a picture of your pet or upload an existing image from your camera roll. Fill out the details such as name, date of birth, breed, and gender, and then choose Add Pet.

This stores the image in an S3 bucket and stores the record in Amazon DynamoDB, using Amazon API Gateway and AWS Lambda. The main screen shows this record and you can click it any time. The records are protected on a per-user basis, which is described later in this post.

Details and customizations

Storing data from your Camera Roll

In the Storage section of the starter repository, there is a walkthrough that describes how to adding capabilities to upload images to an S3 bucket. The image comes from an existing AWS URL in this HOC walkthrough. The starter application, however, contains code for uploading to Amazon S3 using CameraRoll, which requires a native bridge. The logic for this process is contained in the AddPet component, which you can view here and here.

The getPhotos() function pulls the images off of the Camera Roll:

  getPhotos = () => {
    CameraRoll
      .getPhotos({
        first: 20,
      })
      .then(res => {
        this.setState({ images: res.edges })
        this.props.navigation.navigate('UploadPhoto', 
		  { 
		    data: this.state, 
			updateSelectedImage: this.updateSelectedImage 
		})
      })
      .catch(err => console.log('error getting photos...:', err))
  }

You can use this utility function in your React components to open the Camera Roll and return an image. Set the function as a State value called images, which is a list of images passed to a function called updateSelectedImage(). This can be used with the TouchableWithoutFeedback component to show a camera dialog:

<TouchableWithoutFeedback onPress={this.getPhotos}>
{
    selectedImageIndex === null ? (
    <View style={styles.addImageContainer}>
        <Icon size={34} name='camera-roll' color={colors.grayIcon} />
        <Text style={styles.addImageTitle}>Upload Photo</Text>
    </View>
    ) : (
        <Image
        style={styles.addImageContainer}
        source={{ uri: selectedImage.node.image.uri }}
        />
    )
}
</TouchableWithoutFeedback>

The readImage() function is provided to have a consistent object across Android and iOS. The Camera Roll on these platforms is returned differently: on Android, the MIME type is present but it is not present on iOS. This function sets the MIME type on iOS using the result of a lookup on the file extension (for instance PNG will result in image/png).

Modifying the import process

An earlier starter project for React includes details on customizations for the Cloud Logic functionality for Amazon API Gateway and AWS Lambda. You may also want to make changes to the Amazon Cognito configuration or the Amazon DynamoDB settings. If you look in the ./backend/import_mobilehub directory of the repo, there is a file called reactnative-starter.zip, which contains the YAML file that AWS Mobile Hub uses on One-Click import. Open this and look at the following section:

  
database: !com.amazonaws.mobilehub.v0.Database
    components:
      database-nosql: !com.amazonaws.mobilehub.v0.NoSQLDatabase
        tables:
          - !com.amazonaws.mobilehub.v0.NoSQLTable
            attributes:
              petId: S
              userId: S
            hashKeyName: userId
            hashKeyType: S
            rangeKeyName: petId
            rangeKeyType: S
            tableName: ___DYNAMIC_PREFIX___-pets
            tablePrivacy: protected

This section of code is what configures an Amazon DynamoDB table, which the AWS Lambda function uses as part of its environment variables. As outlined in our previous blog post, AWS Mobile Hub creates some default environment variables when importing a project, which you can use in your code. From your cloned repo, open ./backend/lambdas/crud/app.js and notice the following code:

const PETS_TABLE_NAME = `${process.env.MOBILE_HUB_DYNAMIC_PREFIX}-pets`;
AWS.config.update({ region: process.env.REGION });

These variables were automatically added to the AWS Lambda function configuration on import. You can view this in the console by clicking the Cloud Logic section of your Mobile Hub project, expanding the View resource details section, and clicking the Lambda function.

Additionally, in the YAML file are features for sign-in and user-files like in the following snippet:

sign-in: !com.amazonaws.mobilehub.v0.SignIn
    attributes:
      enabled: true
      optional-sign-in: true
    components:
      sign-in-user-pools: !com.amazonaws.mobilehub.v0.UserPoolsIdentityProvider
        attributes:
          alias-attributes:
            - preferred_username
            - phone_number
          mfa-configuration: ON
          name: userpool
          password-policy: !com.amazonaws.mobilehub.ConvertibleMap
            min-length: "8"
            require-lower-case: true
            require-numbers: true
            require-symbols: true
            require-upper-case: true
  user-files: !com.amazonaws.mobilehub.v0.UserFiles
    attributes:
      enabled: true

These features control settings, like the password policy or requiring MFA for the sign-up and sign-in process. You can use them with the starter application and when using this import with the WithAuth HOC. You can also control the creation of the S3 bucket for user content above in the user-files setting.

Fine-grained security controls

The starter application as part of the AWS Mobile Hub import process configures an IAM policy that allows users to read and write only their data. This means that the content they put in S3 buckets is private only to that logged in user and the records in the DynamoDB table (written by Amazon API Gateway and AWS Lambda) can only be read and written by that user.

To view this, in the Mobile Hub console for your project, click Resources on the left of the console and find the section labeled AWS Identity and Access Management Roles. Click the link that starts with reactnativestarter_auth_MOBILEHUB-XXXXXX. This opens the role in the IAM console that the user gets when he or she signs in. There are two policies to look at:

  1. Per-user security on S3: This is controlled by the policy that starts with reactnativestarter_userfiles. If you view the policy JSON, notice that it has Resource settings that look similar to the following:
     "Resource": [
         "arn:aws:s3:::BUCKET/public/*",
         "arn:aws:s3:::BUCKET/protected/${cognito-identity.amazonaws.com:sub}/*",
         "arn:aws:s3:::BUCKET/private/${cognito-identity.amazonaws.com:sub}/*"
     ]
    

These policy variables validate the Amazon Cognito Identity per-user that was assigned upon account registration and initial sign-in. This means that only a specific user can access his or her protected or private folders, while the public folder anyone can access.

  1. Per-user security in API Gateway, Lambda, and DynamoDB: This is controlled by the policy that starts with reactnativestarter_ as well as AWS Lambda. First, note the following condition in the policy JSON:
    "Condition": {
         "ForAllValues:StringEquals": {
             "dynamodb:LeadingKeys": [
                 "${cognito-identity.amazonaws.com:sub}"
             ]
         }
     }
    

This condition controls writes to Amazon DynamoDB in this starter project so that only users can write to their data but everyone can read the database records. You can also modify this policy to apply to both writes and reads as another example.

Finally, since the users access DynamoDB through Amazon API Gateway and AWS Lambda, we extract the identity in the Lambda function. If you view ./backend/lambdas/crud/app.js, you will notice that the condition for reading and writing to Amazon DynamoDB leverages the Amazon Cognito Identity ID:

dynamoDb.query({
    TableName: PETS_TABLE_NAME,
    KeyConditions: {
      userId: {
        ComparisonOperator: 'EQ',
        AttributeValueList: [req.apiGateway.event.requestContext.identity.cognitoIdentityId || UNAUTH],
      },
    },

The value req.apiGateway.event.requestContext.identity.cognitoIdentityId is provided by the AWS Serverless Express middleware library that allows this Lambda function to run as an Express server:

const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware');

Wrapping up

As React Native continues to grow, we’re looking forward to bringing more to the ecosystem with the capabilities of this starter project. We hope the combination of React Native and AWS Mobile Hub accelerates your next project. Please give us feedback in the GitHub issues section of the repository.

Push Notifications with Ionic and Amazon Pinpoint

Engaging your customers through communication channels such as push notifications is important for mobile app success. AWS services such as AWS Mobile Hub and Amazon Pinpoint enable you to do this in a scalable and cost effective manner. When using these services with development tooling like Ionic Framework you can rapidly develop modern applications to build your business.

Ionic recently announced that they are sunsetting their Push and Auth services. We recently launched an Ionic Starter Project and posted a tutorial for adding sign-up and sign-in to an Ionic project to help customers evaluate AWS as an alternative for migration. In this post, we cover how to add push notifications to your Ionic project with Amazon Pinpoint.

In this tutorial, we show how to add push notifications with Google Cloud Messaging (GCM). A similar procedure can be followed for Apple Push Notification service (APNs) which you can find on the Apple Developer website.

(more…)

Easy Sign-in and Sign-up UI with the AWS Mobile SDK for Android

Recently, we released v2.6.0 of the AWS Mobile SDK for Android and AWS Mobile SDK for iOS. It includes many improvements. This post focuses on two of these. First, you can integrate a JSON file with the configuration details of your mobile backend. The easiest way to generate this file is with AWS Mobile Hub. You can also generate the file yourself. Using the JSON file means that you don’t need to edit the Info.plist file (for iOS) or create a class of constants (for Android). You can use the same configuration file for both iOS and Android versions of the app.

Second, we integrated two features that were available only on the AWS Mobile Hub custom SDK. IdentityManager is for managing identity. It includes a UI component for each platform. The component makes it easier to develop a sign-in and sign-up screen. TransferManager is for managing file uploads and downloads. As with IdentityManager, it’s designed for integrating into the UI. Since the custom SDK features have been integrated into the standard SDK, we no longer have a custom SDK for AWS Mobile Hub users.

In this post, we walk through adding analytics and authentication to an existing Android app. The example app is a standalone note-taking app, which you can download from GitHub. Start by downloading and compiling the source code. Set up an emulator and run the code to see how it performs. We used the master-detail project so that the application is responsive to tablets and phones. The app was tested in the emulator for a Nexus 5X and a Pixel C on Android 7.1.1 (API level 25).

(more…)

User Sign-in and Sign-up for Ionic Mobile Apps with Amazon Cognito

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

In our previous blog post, we described how to secure and deploy RESTful interfaces for the Ionic Framework using the AWS SDK for JavaScript and AWS Mobile Hub, with support for authenticated and unauthenticated users. This allows guest users to use your app, with limited privileges, without having an account. When users are ready, they can sign up for an account and sign in. This gives them access to more features in the app. Sign-up and sign-in functionality in a mobile app can be difficult to implement securely and challenging to manage.

In this post, we take a deeper look at how AWS Mobile Hub along with Amazon Cognito provide a foundation for user sign-up and sign-in. We describe how these services integrate in your Ionic Framework mobile app. We use the same sample app introduced in the previous post to showcase the implementation. Refer to the previous blog post for instructions on how to deploy backend resources with Mobile Hub and how to launch the app.

(more…)

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.

(more…)

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.

(more…)

Deploying an EmberJS mobile web application with Mobile Hub

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

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.

(more…)

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 
 */
AWS.config.update({
  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 Amazon.com, 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 : 'XXXXXXXXXXX.cloudfront.net',
aws_mobile_analytics_app_id : 'XXXXXXXXXXXXXXXXXXXXXXX',
aws_project_id : XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX ',
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.