AWS Mobile Blog

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.

Custom Artifacts on AWS Device Farm

A good test report is essential to proper analysis of mobile app testing. It is not only the summary of test results, but also artifacts like screenshots, videos, crash reports, logs, and app-generated files. A well formed test report provides useful insights, leads to faster resolution of issues, and helps teams focus on the right priorities. With so many great testing frameworks available, with their own strengths and weaknesses, the configuration capabilities for reports are important.

AWS Device Farm provides comprehensive test reporting that includes all of the standard capabilities: screenshots, videos, and crash reports. We also know that developers need access to custom reports and artifacts that are generated by the test framework. Today, we are providing access to any custom artifact (log file, test framework generated file, or application generated file) when accessing the test results within AWS Device Farm.
(more…)

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…)

Migrating Users to Amazon Cognito User Pools

Many customers ask about the best way to migrate their existing users in to Amazon Cognito User Pools. In this blog post, we describe the options and provide step-by-step instructions on how to do it.

Amazon Cognito User Pools offer a fully managed user directory so you can easily add sign-up and sign-in to your mobile app or web application. User pools scale to hundreds of millions of users and provide simple, secure, and easy to use options for you as a developer. You can take advantage of enhanced security features, such as email and phone number verification, and multi-factor authentication. User Pools provide a customizable user interface for sign-up and sign-in, and built-in federation with Google, Facebook, Login with Amazon, and SAML-based identity providers. User pool sign-in is based on OpenID Connect and OAuth 2.0 standards.

(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…)

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

This 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.  I will cover authentication in the second part of this blog.

(more…)

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.

(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…)