From @akolybelnikov on Sat Nov 11 2017 13:01:51 GMT+0000 (UTC)
@jayair what if I needed to lay one route open to not-signed in users, for example render example notes created by the admin with his access permissions? How can I bypass the sign-in functionality and send a get request to fetch data from a DynamoDB table? Do I have to create a new Iam user in order to achieve that?
From @jayair on Sat Nov 11 2017 19:47:43 GMT+0000 (UTC)
@akolybelnikov Youād need to create an API without an authorizer - https://github.com/AnomalyInnovations/serverless-stack-demo-api/blob/master/serverless.yml#L69. And in the awsLib.js
for the React portion, just skip signing the request and directly make a fetch
call - https://github.com/AnomalyInnovations/serverless-stack-demo-client/blob/master/src/libs/awsLib.js#L17.
From @NYCSwan on Fri Feb 09 2018 17:06:47 GMT+0000 (UTC)
Hi! Iām working through your tutorial and have hit a snag. Iāve adapted the tutorial for the project Iām working on so there are a few extra functions and db tables. I donāt think thatās where the problem stems from after following your debugging instructions but wanted to mention that in case it is the problem. Essentially, I can invoke the api gateway fns from the terminal with āsls deployā and get the correct response. However, when I try to do the same from the react app, it comes through cloudwatch but doesnāt pass into the app. The result var in componentWIllMount after invokeapig is ā{}ā.
I have quadruple checked that all of my files match what is in the tutorial. Followed the error in cloudwatch and it returns the correct information (garden aka note in the tutorial) with a 200 status. I have stepped through the entire app in debugger and canāt find where the response body comes in. I can successfully post a new garden to the db.
The awsLibs invokespig() returns this result:
Response {type: "cors", url: "https://API_GATEWAY.execute-api.us-east-1.amazonaws.com/prod/gardens", redirected: false, status: 200, ok: true, ā¦}
The body attr is a ReadableStream.
My Notes/gardens page:
class Gardens extends Component {
static propTypes = {
match: PropTypes.shape({
path: PropTypes.string
}).isRequired,
isAuthenticated: PropTypes.bool.isRequired
};
state = {
chamberId: 1,
chamberData: [],
growingPlants: [],
chambers: [],
isLoading: true
};
async componentDidMount() {
console.log('componentDidMount monitor');
try {
const growingResults = await this.growingPlants();
this.setState({growingPlants: growingResults});
} catch(e) {
console.log(e);
}
this.setState({ isLoading: false });
}
growingPlants = () => {
console.log('get growing plants from db');
return invokeApig({ path: "/gardens" }); // eslint-disable-line
}
renderGardensList(chambers) {
return [{}].concat(gardens).map(
(garden, i) =>
i !== 0
? <ListGroupItem
key={garden.chamberId}
href={`/gardens/${gardens.chamberId}`}
onClick={this.handleNoteClick}
header={gardens.chamberName}
>
{"Created: " + new Date(garden.createdAt).toLocaleString()}
</ListGroupItem>
: <ListGroupItem
key="new"
href="/NewGrow"
onClick={this.handleChamberClick}
>
<h4>
<b>{"\uFF0B"}</b> Start a new Garden
</h4>
</ListGroupItem>
);
}
handleGardenClick = event => {
event.preventDefault();
this.props.history.push(event.currentTarget.getAttribute("href"));
}
renderGardens() {
return (
<div className="gardens">
<PageHeader>Your Gardens</PageHeader>
<ListGroup>
{!this.state.isLoading && this.renderGardensList(this.state.growingPlants)}
</ListGroup>
</div>
);
}
renderLander() {..}
render() {
return (
<div className="monitor container">
{this.props.isAuthenticated ? this.renderChambers() : this.renderLander()}
</div>
)}};
My AWS permissions for the auth_role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*",
"cognito-identity:*"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::MY_BUCKET/${cognito-identity.amazonaws.com:sub}*",
"arn:aws:s3:::ANOTHER_BUCKET/${cognito-identity.amazonaws.com:sub}*",
"arn:aws:s3:::BUCKET_FOR_MY_APP/${cognito-identity.amazonaws.com:sub}*",
"arn:aws:s3:::DEPLOYMENT_BUCKET/${cognito-identity.amazonaws.com:sub}*"
]
},
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke"
],
"Resource": [
"arn:aws:execute-api:us-east-1:*:MY_API_GATEWAY_ID/*"
]
},
{
"Effect": "Allow",
"Action": [
"dynamodb:*"
],
"Resource": [
"arn:aws:dynamodb:us-east-1:*:table/*"
]
}
]
}
Thanks in advance for the help and this tutorial has saved me so many hours of confusion. Itās seriously one of the best Iāve tried
From @jayair on Fri Feb 09 2018 18:29:55 GMT+0000 (UTC)
@NYCSwan Hmm so you are able to write to the db but when you read from it you get an empty result with a 200 status?
It might be that the table you are writing to (with the user id) and the one you are fetching from is not the same?
From @NYCSwan on Sat Feb 10 2018 00:57:51 GMT+0000 (UTC)
@jayair You got it. I can write to the db but it returns an empty hash when I try to get or list items from a table. I found another bug when I try to get one single item. I get a 403 preflight cors issue or TypeError: body stream already read error. Iām fetching and reading from the same table.
Get Method
getGarden = () => {
console.log('get indiv garden');
// debugger
return invokeApig({ path: `/gardens/${TIMESTAMP}`});
};
Iām watching the actual lambdas & API-Gateway-Execution-Logs
logs from /gardens/{id}:
...
message: 'The provided key element does not match the schema',
code: 'ValidationException',
time: 2018-02-09T22:42:51.694Z,
requestId: 'CQ2Q628G3DNR2L6MH8NHFDCV3RVXXXXO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 5.994444151965716 }
2018-02-09T22:42:51.703Z 8f1bc406-0dea-11e8-b61e-d167a9b81557
{
"status": false
}
END RequestId: 8f1bc406-0dea-11e8-b61e-d167a9b81557
REPORT RequestId: 8f1bc406-0dea-11e8-b61e-d167a9b81557 Duration: 155.51 ms Billed Duration: 200 ms Memory Size: 1024 MB Max Memory Used: 37 MB
START RequestId: ca9dfd41-0dea-11e8-bb46-df0bb292ce1c Version: $LATEST
2018-02-09T22:44:30.899Z ca9dfd41-0dea-11e8-bb46-df0bb292ce1c
{
"gardenId": "049d18e0-0d96-11e8-83ad-a9620d2006bc",
"chamberId": "Chamber 2",
"climateId": "2",
"userId": "us-east-1:1a372091-157f-48e9-bc27-9d664a7f7718",
"plantName": "Kale",
"createdAt": 1518179860859,
"plantRecipeId": "3"
}
END RequestId: ca9dfd41-0dea-11e8-bb46-df0bb292ce1c
REPORT RequestId: ca9dfd41-0dea-11e8-bb46-df0bb292ce1c Duration: 88.78 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 37 MB
From the api_gateway logs, Is Method: OPTIONS the issue? In the same minute/call, there are two logs to /gardens path, the top is METHOD: GET, the second is OPTIONS. I canāt find anything that mentions this.
(2b11aa94-0de5-11e8-9e91-69a8d6edbe9f) HTTP Method: OPTIONS, Resource Path: /gardens
(2b11aa94-0de5-11e8-9e91-69a8d6edbe9f) Method request path:
{}
(2b11aa94-0de5-11e8-9e91-69a8d6edbe9f) Method request query string:
{}
(2b11aa94-0de5-11e8-9e91-69a8d6edbe9f) Method request headers: {Accept=*/*, CloudFront-Viewer-Country=US, CloudFront-Forwarded-Proto=https, CloudFront-Is-Tablet-Viewer=false, origin=http://localhost:3000, CloudFront-Is-Mobile-Viewer=true, Referer=http://localhost:3000/controls/ExistingGrow, User-Agent=Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1, X-Forwarded-Proto=https, CloudFront-Is-SmartTV-Viewer=false, Host=az9ohrt4i7.execute-api.us-east-1.amazonaws.com, Accept-Encoding=gzip, deflate, br, dnt=1, access-control-request-method=GET, X-Forwarded-Port=443, X-Amzn-Trace-Id=Root=1-5a7e1adf-35b2160342d43365353cef70, Via=2.0 f564d0c1e4568b2b822f986a309f4114.cloudfront.net (CloudFront), access-control-request-headers=authorization,content-type,x-amz-date,x-amz-security-token, X-Amz-Cf-Id=j8QmzcWlIRC2h5fsRq_L237a65ZYHerqsN-kMqNg2Orxub0Pd3jO-Q==, X-Forwarded-For=68.174.1.162, 204.246.168.11, Accept-Language=en-US,en;q=0.9, CloudFront-Is-Desktop-Viewer=false}
(2b11aa94-0de5-11e8-9e91-69a8d6edbe9f) Method request body before transformations:
(2b11aa94-0de5-11e8-9e91-69a8d6edbe9f) Received response. Integration latency: 0 ms
(2b11aa94-0de5-11e8-9e91-69a8d6edbe9f) Endpoint response body before transformations:
(2b11aa94-0de5-11e8-9e91-69a8d6edbe9f) Endpoint response headers:
{}
(2b11aa94-0de5-11e8-9e91-69a8d6edbe9f) Method response body after transformations:
(2b11aa94-0de5-11e8-9e91-69a8d6edbe9f) Method response headers: {Access-Control-Allow-Origin=*, Access-Control-Allow-Credentials=false, Access-Control-Allow-Methods=OPTIONS,GET,POST, Access-Control-Allow-Headers=Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent, Content-Type=application/json}
(8e8be017-0dea-11e8-8f95-0f0011862800) Method request body before transformations:
(8e8be017-0dea-11e8-8f95-0f0011862800) Received response. Integration latency: 0 ms
(8e8be017-0dea-11e8-8f95-0f0011862800) Endpoint response body before transformations:
(8e8be017-0dea-11e8-8f95-0f0011862800) Endpoint response headers:
{}
(8e8be017-0dea-11e8-8f95-0f0011862800) Method response body after transformations:
(8e8be017-0dea-11e8-8f95-0f0011862800) Method response headers: {Access-Control-Allow-Origin=*, Access-Control-Allow-Credentials=false, Access-Control-Allow-Methods=OPTIONS,GET,POST, Access-Control-Allow-Headers=Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent, Content-Type=application/json}
(8e8be017-0dea-11e8-8f95-0f0011862800) Successfully completed execution
(8e8be017-0dea-11e8-8f95-0f0011862800) Method completed with status: 200
The /gardens log:
2018-02-09T22:42:50.711Z 8e95f28a-0dea-11e8-85af-757fe33d1b3a [
{
"gardenId": "049d18e0-0d96-11e8-83ad-a9620d2006ca",
"chamberId": "Chamber 1",
"climateId": "2",
"userId": "us-east-1:1a372091-157f-48e9-bc27-9d664a7f7718",
"plantName": "Cilantro",
"createdAt": 1518179860846,
"plantRecipeId": "2"
}
,
{
"gardenId": "049d18e0-0d96-11e8-83ad-a9620d2006bc",
"chamberId": "Chamber 2",
"climateId": "2",
"userId": "us-east-1:1a372091-157f-48e9-bc27-9d664a7f7718",
"plantName": "Kale",
"createdAt": 1518179860859,
"plantRecipeId": "3"
}
,
{
"gardenId": "47aede70-0dbe-11e8-9a81-b7b8232688ef",
"chamberId": "Chamber 3",
"climateId": "2",
"userId": "us-east-1:1a372091-157f-48e9-bc27-9d664a7f7718",
"plantName": "Cilantro",
"createdAt": 1518197153239,
"plantRecipeId": "2"
}
]
END RequestId: 8e95f28a-0dea-11e8-85af-757fe33d1b3a
From @jayair on Mon Feb 12 2018 19:54:47 GMT+0000 (UTC)
@NYCSwan This The provided key element does not match the schema
is not good. It sounds like the table has not been set up properly. What does the table structure look like right now? And the query you are using to get an object?
From @jayair on Fri Mar 30 2018 22:27:56 GMT+0000 (UTC)
@mbahfauz Can you please not post the same issue in multiple threads? Also, for large code samples link to a Gist from elsewhere.
From @nelsoftcom on Wed Apr 04 2018 21:36:41 GMT+0000 (UTC)
Help Again please - When Iām trying to list the notes -> getting an error - TypeMismatchError.
thank you
From @jayair on Wed Apr 04 2018 22:29:42 GMT+0000 (UTC)
@nelsoftcom Can I see a screenshot of the error?
From @nuyulcore on Fri Apr 06 2018 07:29:57 GMT+0000 (UTC)
Hello jay, thanks for your support before, I can render image on list now. But I still got little problem. How can I get image url of every note on home page (List notes). Because I only get name of file on database, But still confuse how to get those image url on list notes.
From @jayair on Fri Apr 06 2018 18:52:54 GMT+0000 (UTC)
@nelsoftcom I think we need a bit more than that to debug it. Can you try it on Chrome and look at what shows up in the console?
From @jayair on Fri Apr 06 2018 18:53:53 GMT+0000 (UTC)
@mbahfauz If you can render it in the notes, why not return it on the list page and do the same?
From @nuyulcore on Sat Apr 07 2018 15:41:51 GMT+0000 (UTC)
I had try to render it with {Storage.get(ānotes.attachmentā)} But I always got error, this is not react component. If you try to render array, xxxxx
From @jayair on Sat Apr 07 2018 20:13:49 GMT+0000 (UTC)
@mbahfauz Yeah you canāt directly use that in your component. It returns a promise and you need to set it after it returns. Notice what we do with it here - https://github.com/AnomalyInnovations/serverless-stack-demo-client/blob/master/src/containers/Notes.js#L31.
From @btotharye on Tue Apr 17 2018 01:36:40 GMT+0000 (UTC)
any idea why when I click on a note it takes me to the right ID page in the URL and I can see the console.log of the object but it always says page not found like its not loading the notes when I click them but its loading them fine in the list and creating them fine, just not loading the page when I click on a note, any idea what might be doing this? No errors in the console atm.
From @jayair on Tue Apr 17 2018 18:11:38 GMT+0000 (UTC)
@btotharye Does it fail to load when you go to the URL directly?
From @btotharye on Tue Apr 17 2018 18:17:59 GMT+0000 (UTC)
I just redid it and itās fine not sure what the issue was, thanks
From @nuyulcore on Sun Apr 22 2018 07:06:33 GMT+0000 (UTC)
Anyone know how to call notes for not authorize user?
I had try with this code:
async componentDidMount() { const coins = await this.coins(); this.setState({ coins }); this.setState({ isLoading: false }); }
But got not creditentials.
Thanks