Chaitanya
Chaitanya

Reputation: 3638

Unable to fetch user information from AWS cognito using AWS Lambda service

This is my first lambda being written in JS. I am trying to fetch the user information from AWS Cognito using lambda function. For this, I am using the Javascript SDK provided by AWS. My code is as follows

'use strict';

exports.handler = async (event) => {
    const AWS = require('aws-sdk');
    var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'});
    var params = {
    AccessToken: 'my-access-token'
    };
    
    console.log('Getting info from cognito ${cognitoidentityserviceprovider}');
    cognitoidentityserviceprovider.getUser(params, function(err, data) {
    if (err) {
        console.log('In error stack of cognito call');
        console.log(err, err.stack); // an error occurred
        }
    else{
        console.log('In success stack of cognito call');
        console.log(data);           // successful response
        }
    });
    console.log('completed call from cognito');
    
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

My function logs are as follows

Function logs:
START RequestId: func-Id1 Version: $LATEST
2020-09-07T14:18:05.647Z    func-Id1    INFO    Start the lambda function
2020-09-07T14:18:10.531Z    func-Id1    INFO    Getting info from cognito ${cognitoidentityserviceprovider}
2020-09-07T14:18:10.893Z    func-Id1    INFO    completed call from cognito
END RequestId: func-Id1

Now, the issue that I am facing is that I am not able to retrieve any information from cognito. I neither receive the success response nor the error message. Could anyone please suggest as to what I am missing in my lambda function ? TIA

Upvotes: 0

Views: 836

Answers (2)

lemming
lemming

Reputation: 1863

I think your Lambda function is returning the response and completing before the cognitoidentityserviceprovider.getUser() function's callback is executed on return of the response.

The call to cognitoidentityserviceprovider.getUser() is non-blocking. In other words, it won't wait for the callback to execute, but will rather continue to execute the rest of the code.

You can do one of two things depending on how you decide to handle your asynchronous code:

Use Async/Await

Your Lambda function is currently using the async keyword, which expects you to use the corresponding await keyword to handle asynchronous requests, e.g.:

try {
    const user = await cognitoidentityserviceprovider.getUser(params).promise();
    return {
        statusCode: 200,
        user: user
    };
} catch(error) {
    return {
        statusCode: 500,
        error: error
    };
}

or even just:

const AWS = require('aws-sdk');
const cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18','us-east-1'});
exports.handler = async (event) => {
    const params = {
        AccessToken: 'my-access-token'
    };
    return cognitoidentityserviceprovider.getUser(params).promise();
};

Using Callbacks

Remove the async keyword and add 2 more parameters to your Lambda function definition:

exports.handler = (events, context, callback) => {
    ...
}

then use the Lambda's callback parameter to return the response when your cognitoidentityserviceprovider.getUser() request's callback returns.

cognitoidentityserviceprovider.getUser(params, (err, data) => {
    if (err) {
        console.log('In error stack of cognito call');
        done(err);
    } else {
        console.log('In success stack of cognito call');
        done(null, data);
    }
});
... no need for a return statement ...

For more information see this page on handlers in the Lambda docs

Upvotes: 1

F_SO_K
F_SO_K

Reputation: 14799

I think your lambda is timing out.

  1. Move your SDK initialisation outside of the handler, this will greatly speed up your cold start time (from about 5s to less than a second) as it will use the SDK in the provisioned environment.
  2. Increase your lambda timeout, looks like its on 5 seconds?
  3. You're not getting an error message yet but I think you're going to need to set a region in your AWS config.
'use strict'; const AWS = require('aws-sdk'); var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18','us-east-1'});

exports.handler = async (event) => {

var params = {
AccessToken: 'my-access-token'
};

console.log('Getting info from cognito ${cognitoidentityserviceprovider}');
cognitoidentityserviceprovider.getUser(params, function(err, data) {
if (err) {
    console.log('In error stack of cognito call');
    console.log(err, err.stack); // an error occurred
    }
else{
    console.log('In success stack of cognito call');
    console.log(data);           // successful response
    }
});
console.log('completed call from cognito');

const response = {
    statusCode: 200,
    body: JSON.stringify('Hello from Lambda!'),
};
return response;

};

Sorry about the formatting I tried and tried but this code refused to be markedup!

Upvotes: 1

Related Questions