AWS Lambda
Developer Guide

Tutorial: Using AWS Lambda as Mobile Application Backend

In this tutorial, you create a simple Android mobile application. The primary purpose of this tutorial is to show you how to hook up various components to enable an Android mobile application to invoke a Lambda function and process response.

Prerequisites

This tutorial assumes that you have some knowledge of basic Lambda operations and the Lambda console. If you haven't already, follow the instructions in Getting Started to create your first Lambda function.

To follow the procedures in this guide, you will need a command line terminal or shell to run commands. Commands are shown in listings preceded by a prompt symbol ($) and the name of the current directory, when appropriate:

~/lambda-project$ this is a command this is output

For long commands, an escape character (\) is used to split a command over multiple lines.

On Linux and macOS, use your preferred shell and package manager. On Windows 10, you can install the Windows Subsystem for Linux to get a Windows-integrated version of Ubuntu and Bash.

Create the Execution Role

Create the execution role that gives your function permission to access AWS resources.

To create an execution role

  1. Open the roles page in the IAM console.

  2. Choose Create role.

  3. Create a role with the following properties.

    • Trusted entityAWS Lambda.

    • PermissionsAWSLambdaBasicExecutionRole.

    • Role namelambda-android-role.

The AWSLambdaBasicExecutionRole policy has the permissions that the function needs to write logs to CloudWatch Logs.

Create the Function

The following example uses data to generate a string reponse.

Note

For sample code in other languages, see Sample Function Code.

Example index.js

exports.handler = function(event, context, callback) { console.log("Received event: ", event); var data = { "greetings": "Hello, " + event.firstName + " " + event.lastName + "." }; callback(null, data); }

To create the function

  1. Copy the sample code into a file named index.js.

  2. Create a deployment package.

    $ zip function.zip index.js
  3. Create a Lambda function with the create-function command.

    $ aws lambda create-function --function-name AndroidBackendLambdaFunction \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs8.10 \ --role role-arn

Test the Lambda Function

Invoke the function manually using the sample event data.

To test the Lambda function (AWS CLI)

  1. Save the following sample event JSON in a file, input.txt.

    { "firstName": "first-name", "lastName": "last-name" }
  2. Execute the following invoke command:

    $ aws lambda invoke --function-name AndroidBackendLambdaFunction \ --payload file://file-path/input.txt outputfile.txt

Create an Amazon Cognito Identity Pool

In this section, you create an Amazon Cognito identity pool. The identity pool has two IAM roles. You update the IAM role for unauthenticated users and grant permissions to execute the AndroidBackendLambdaFunction Lambda function.

For more information about IAM roles, see IAM Roles in the IAM User Guide. For more information about Amazon Cognito services, see the Amazon Cognito product detail page.

To create an identity pool

  1. Open the Amazon Cognito console.

  2. Create a new identity pool called JavaFunctionAndroidEventHandlerPool. Before you follow the procedure to create an identity pool, note the following:

    • The identity pool you are creating must allow access to unauthenticated identities because our example mobile application does not require a user log in. Therefore, make sure to select the Enable access to unauthenticated identities option.

    • Add the following statement to the permission policy associated with the unauthenticated identities.

      { "Effect": "Allow", "Action": [ "lambda:InvokeFunction" ], "Resource": [ "arn:aws:lambda:us-east-1:123456789012:function:AndroidBackendLambdaFunction" ] }

      The resulting policy will be as follows:

      { "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":[ "mobileanalytics:PutEvents", "cognito-sync:*" ], "Resource":[ "*" ] }, { "Effect":"Allow", "Action":[ "lambda:invokefunction" ], "Resource":[ "arn:aws:lambda:us-east-1:account-id:function:AndroidBackendLambdaFunction" ] } ] }

    For instructions about how to create an identity pool, log in to the Amazon Cognito console and follow the New Identity Pool wizard.

  3. Note the identity pool ID. You specify this ID in your mobile application you create in the next section. The app uses this ID when it sends request to Amazon Cognito to request for temporary security credentials.

Create an Android Application

Create a simple Android mobile application that generates events and invokes Lambda functions by passing the event data as parameters.

The following instructions have been verified using Android studio.

  1. Create a new Android project called AndroidEventGenerator using the following configuration:

    • Select the Phone and Tablet platform.

    • Choose Blank Activity.

  2. In the build.gradle (Module:app) file, add the following in the dependencies section:

    compile 'com.amazonaws:aws-android-sdk-core:2.2.+' compile 'com.amazonaws:aws-android-sdk-lambda:2.2.+'
  3. Build the project so that the required dependencies are downloaded, as needed.

  4. In the Android application manifest (AndroidManifest.xml), add the following permissions so that your application can connect to the Internet. You can add them just before the </manifest> end tag.

    <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  5. In MainActivity, add the following imports:

    import com.amazonaws.mobileconnectors.lambdainvoker.*; import com.amazonaws.auth.CognitoCachingCredentialsProvider; import com.amazonaws.regions.Regions;
  6. In the package section, add the following two classes (RequestClass and ResponseClass). Note that the POJO is same as the POJO you created in your Lambda function in the preceding section.

    • RequestClass. The instances of this class act as the POJO (Plain Old Java Object) for event data which consists of first and last name. If you are using Java example for your Lambda function you created in the preceding section, this POJO is same as the POJO you created in your Lambda function code.

      package com.example....lambdaeventgenerator; public class RequestClass { String firstName; String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public RequestClass(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public RequestClass() { } }
    • ResponseClass

      package com.example....lambdaeventgenerator; public class ResponseClass { String greetings; public String getGreetings() { return greetings; } public void setGreetings(String greetings) { this.greetings = greetings; } public ResponseClass(String greetings) { this.greetings = greetings; } public ResponseClass() { } }
  7. In the same package, create interface called MyInterface for invoking the AndroidBackendLambdaFunction Lambda function.

    package com.example.....lambdaeventgenerator; import com.amazonaws.mobileconnectors.lambdainvoker.LambdaFunction; public interface MyInterface { /** * Invoke the Lambda function "AndroidBackendLambdaFunction". * The function name is the method name. */ @LambdaFunction ResponseClass AndroidBackendLambdaFunction(RequestClass request); }

    The @LambdaFunction annotation in the code maps the specific client method to the same-name Lambda function. For more information about this annotation, see AWS Lambda in the AWS Mobile SDK for Android Developer Guide.

  8. To keep the application simple, we are going to add code to invoke the Lambda function in the onCreate() event handler. In MainActivity, add the following code toward the end of the onCreate() code.

    // Create an instance of CognitoCachingCredentialsProvider CognitoCachingCredentialsProvider cognitoProvider = new CognitoCachingCredentialsProvider( this.getApplicationContext(), "identity-pool-id", Regions.US_WEST_2); // Create LambdaInvokerFactory, to be used to instantiate the Lambda proxy. LambdaInvokerFactory factory = new LambdaInvokerFactory(this.getApplicationContext(), Regions.US_WEST_2, cognitoProvider); // Create the Lambda proxy object with a default Json data binder. // You can provide your own data binder by implementing // LambdaDataBinder. final MyInterface myInterface = factory.build(MyInterface.class); RequestClass request = new RequestClass("John", "Doe"); // The Lambda function invocation results in a network call. // Make sure it is not called from the main thread. new AsyncTask<RequestClass, Void, ResponseClass>() { @Override protected ResponseClass doInBackground(RequestClass... params) { // invoke "echo" method. In case it fails, it will throw a // LambdaFunctionException. try { return myInterface.AndroidBackendLambdaFunction(params[0]); } catch (LambdaFunctionException lfe) { Log.e("Tag", "Failed to invoke echo", lfe); return null; } } @Override protected void onPostExecute(ResponseClass result) { if (result == null) { return; } // Do a toast Toast.makeText(MainActivity.this, result.getGreetings(), Toast.LENGTH_LONG).show(); } }.execute(request);
  9. Run the code and verify it as follows:

    • The Toast.makeText() displays the response returned.

    • Verify that CloudWatch Logs shows the log created by the Lambda function. It should show the event data (first name and last name). You can also verify this in the AWS Lambda console.