Я работаю над мобильным проектом, в котором я хотел бы использовать AWS в качестве своего бэкэнда.Использование лямбда-функций особенно привлекательно, поскольку они очень дешевы по сравнению с вызовами AWS API Gateway.Однако я не могу успешно вызывать лямбда-функцию из моего мобильного приложения, потому что время ожидания на бэкэнде истекло.
Поскольку я хотел бы также иметь версию для iOS, я 'м с использованием Xamarin.Похоже, в AWS есть отличные библиотеки для Xamarin.
Я использую следующие пакеты NuGet: AWSSDK.Lambda
AWSSDK.CognitoIdentity
Вот код моего мобильного приложения:
[Activity(Label = "MyApp.Android", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
EditText email;
EditText password;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
var registerButton = FindViewById<Button>(Resource.Id.registerButton);
registerButton.Click += onRegisterClicked;
email = FindViewById<EditText>(Resource.Id.email);
password = FindViewById<EditText>(Resource.Id.password);
}
private async void onRegisterClicked(object sender, EventArgs e)
{
try
{
var credentials = new Amazon.CognitoIdentity.CognitoAWSCredentials("us-east-2:0a6...", Amazon.RegionEndpoint.USEast2);
var lambdaConfig = new Amazon.Lambda.AmazonLambdaConfig();
lambdaConfig.RegionEndpoint = Amazon.RegionEndpoint.USEast2;
var client = new Amazon.Lambda.AmazonLambdaClient(credentials, lambdaConfig);
var invokeRequest = new Amazon.Lambda.Model.InvokeRequest();
invokeRequest.FunctionName = "userHandler";
invokeRequest.InvocationType = Amazon.Lambda.InvocationType.RequestResponse;
var emailAddress = email.Text;
var userPassword = password.Text;
var payload = new { type = "register", email = emailAddress, password = userPassword };
invokeRequest.Payload = JsonConvert.SerializeObject(payload);
try
{
var results = await client.InvokeAsync(invokeRequest); // failure here. no exception thrown. just hangs
}
catch (Exception e1)
{
var exceptionMsg1 = e1.Message;
// initially had exception ...:assumed-role/Cognito_Unauth_Role?CognitoIdentityCredentials is not authorized to perform: lambda:InvokeFunction on resource: ...:userHandler
// added lambda invoke policy but now just hangs
}
}
catch (Exception e2)
{
var exceptionMsg2 = e2.Message;
}
}
}
Первоначально я получил исключение с сообщением что-то вроде ...:assumed-role/Cognito_Unauth_Role?CognitoIdentityCredentials is not authorized to perform: lambda:InvokeFunction on resource: ...:userHandler
.Без проблем.Мне просто нужно добавить эту политику в Cognito_Unauth_Role
, верно?
Так что я добавил лямбда-политику вызова для этой роли.Теперь вместо получения исключений он просто навсегда висит на линии var results = await client.InvokeAsync(invokeRequest);
.
Я посмотрел в журналах AWS Cloudwatch.И похоже, что мой лямбда-запрос проходит, но он говорит, что он истекает через 10 секунд, и после нескольких попыток кажется, что он прекращает принимать запросы полностью.
Теперь, клянусь, когда я тестировал эту лямбда-функцию на сервере до того, как заработал .Теперь по какой-то странной причине это время ожидания, когда я проверяю лямбда-функцию в AWS в своем браузере.
Я дал тесту много времени (30 секунд) и время ожидания истекло.
Вот мой внутренний код nodejs:
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
const config = require('./config.json');
const poolData = {
UserPoolId: config.poolId,
ClientId: config.appClientId
};
const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
function registerUser(email, password) {
var attributes = [new AmazonCognitoIdentity.CognitoUserAttribute({ Name: 'email', Value: email })];
return new Promise((resolve, reject) => {
userPool.signUp(email, password, attributes, null, function (err, results) {
if (err) {
reject(err);
}
else {
resolve(results);
}
});
});
}
exports.handler = async (event) => {
console.log('here is the event:');
console.log(typeof (event));
console.log(event); // this all seems legit
if (event && event.type === 'register' && event.email && event.password) {
console.log('registering...'); // times out here
var registerResponse = await new Promise((resolve, reject) => {
registerUser(event.email, event.password).then((results) => {
console.log('registration response recieved');
resolve({
statusCode: 200,
body: JSON.stringify(results)
});
}, (reason) => {
console.log('some errr'); // not getting here
console.log(reason);
resolve({
statusCode: 400,
body: JSON.stringify(reason)
});
}).catch((error) => {
console.log('some error caught'); // not getting here
console.log(error);
});
});
return registerResponse;
}
// never getting here. timing out.
const response = {
statusCode: 200,
body: 'idk what is happening'
};
return response;
};
Я не могуподумайте, почему это больше не работает.Разве я не должен регистрировать пользователей в AWS Cognito с помощью лямбда-функции?Единственное, что я изменил между тем, когда оно работало, и когда оно не было, - это некоторые изменения в конфигурации Identity Pool, чтобы позволить неавторизованным пользователям вызывать лямбда-функцию.
Почему сейчас истекает время?Нужно ли обрабатывать регистрацию пользователей и вход в систему с помощью AWS Cognito через AWS API Gateway?
Вот пользователи AWS Cognito, которые я зарегистрировал ранее с помощью своей лямбда-функции:
А теперь не работает!Почему!?