* Which Category is your question related to? *
GraphQL
* What AWS Services are you utilizing? *
AppSync, Cognito
* Provide additional details e.g. code snippets *
I'm using the GraphQL API + Cognito and I'm trying to describe a model where I have something like this:
type List @model {
id: ID!
name: String!
author: User @connection
}
type User @model {
id: ID!
name: String!
picture: String
email: String!
phone_number: String!
org: Org @connection(name: "OrgUsers")
}
type Org @model {
id: ID!
name: String!
users: [User] @connection(name: "OrgUsers")
}
I want to be able to list all the users from an Organisation, get a User by Id, etc, using the GraphQL API. The thing is that I don't understand how can I associate the Cognito users with the ones in the model. My try was to create a new User in a Lambda with postConfirmation trigger, but I'm getting a cyclic dependency error (cognito -> postConfirmation -> graphqlapi -> cognito)... Also, it seems just wrong to have duplicated data between cognito and dynamodb. This seems a quite common use case but I can't find any information on the docs and in this repo. What am I missing?
I created indeed a lambda function as a post confirmation trigger. What it does it sends the user ID to a dynamodb table. I also have been looking for other options, but if you want user data listed in your app this is your way.
@rpostulart Could you publish a gist explaining how did you insert it in a DynamoDB table? I added the Users table via amplify add api and it seems that I can't insert an item from Lambda if it was created that way
I create a function via amplify:
var AWS = require('aws-sdk');
var dynamodb = new AWS.DynamoDB();
exports.handler = (event, context, callback) => {
console.log('add to database');
var tableName = 'User dynamodb TABLE' // or set dynamic via process.env
var userID = event.request.userAttributes.sub;
dynamodb.putItem( {
TableName: tableName,
Item: {
id: {S: userID},
},
},
function(err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
callback(err, null);
} else {
callback(null, data);
}
},
);
};
In the cloudformation-template.json of your function (in amplify > backend > function) add this statement to lambdaexecutionpolicy area:
{
"Effect": "Allow",
"Action": [
"dynamodb:PutItem"
],
"Resource": {
"Fn::Sub": [
"arn:aws:dynamodb:${region}:${account}:table/*",
{
"region": {
"Ref": "AWS::Region"
},
"account": {
"Ref": "AWS::AccountId"
}
}
]
}
}
@elgutierrez Let me know if you're still stuck after @rpostulart response.
@kaustavghosh06
I only face a problem now with this lambda function which I didn't had before, has there been a change which impacted this lambda. Error:
Invalid lambda function output : Invalid JSON (Service: AWSCognitoIdentityProviderService; Status Code: 400; Error Code: InvalidLambdaResponseException; Request ID: cfa3a834-1ea2-4948-bf31-42a08cbeae1d)
@kaustavghosh06 Yes, but now I have the same issue as @rpostulart. What are we supposed to return as result of the lambda function?
@rpostulart Hey, just to let you know that I found the solution for this issue. You should call a method at the end of the lambda execution:
exports.handler = (event, context, callback) => {
...
context.done(null, event)
};
I tested this in the putItem function that didn't work of course. Thx. Success!
Most helpful comment
I create a function via amplify:
In the cloudformation-template.json of your function (in amplify > backend > function) add this statement to lambdaexecutionpolicy area: