I'm trying to filter the results of a scan of a DynamoDB table using a FilterExpression in my query. I'm using a Lambda function deployed on API Gateway on AWS.
Function Querying the Endpoint
// Scan the table for entries and use data to populate HTML table.
async function scanTable(){
var query = {
TableName: "bookings",
ProjectionExpression: "id, username, start_booking, end_booking",
FilterExpression: "username = :u",
ExpressionAttributeValues: {":u":"human#gmail.com"}
};
try{
const response = await axios({ method: 'get', url: `${url}/bookings`, params: query });
}catch(err){
console.log(err);
}
}
Lambda Function
'use strict'
const AWS = require('aws-sdk');
exports.handler = async (event, context) => {
const documentClient = new AWS.DynamoDB.DocumentClient({convertEmptyValues: true});
let responseBody = "";
let statusCode = 0;
const params = (event.queryStringParameters);
// console.log(params);
try{
const data = await documentClient.scan(params).promise();
responseBody = JSON.stringify(data.Items);
statusCode = 200;
}catch(err){
responseBody = `Unable to get the bookings: ${err}`;
statusCode = 403;
}
console.log("Response Body: " + responseBody);
const response = {
statusCode: statusCode,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
body: responseBody
};
return response;
}
The complete error I receive is
ValidationException: ExpressionAttributeValues contains invalid key: Syntax error; key: "11"
where the key value at the end of the error (key:"11") changes somewhat dependent on the value assigned in ExpressionAttributeValues. I've tried to follow the FilterExpression example in the DynamoDB Docs for the scan function to no avail. Here is another example.
Here is a similar question from the AWS forums.
Related
I'm trying to figure out how to delete information submitted to the firebase database.
I am trying to delete information under the requests. Example
Here are my actions used to fetch the data:
export default {
async contactArtist(context, payload) {
const newRequest = {
userEmail: payload.email,
message: payload.message
};
const response = await fetch(`https://find-artist-d3495-default-rtdb.firebaseio.com/requests/${payload.artistId}.json`, {
method: 'POST',
body: JSON.stringify(newRequest)
});
const responseData = await response.json();
if (!response.ok) {
const error = new Error(responseData.message || 'Failed to send request.');
throw error;
}
newRequest.id = responseData.name;
newRequest.artistId = payload.artistId;
context.commit('addRequest', newRequest);
},
async fetchRequests(context) {
const artistId = context.rootGetters.userId;
const token = context.rootGetters.token;
const response = await fetch(`https://find-artist-d3495-default-rtdb.firebaseio.com/requests/${artistId}.json?auth=` + token);
const responseData = await response.json();
if (!response.ok) {
const error = new Error(responseData.message || 'Failed to fetch requests.');
throw error;
}
const requests = [];
for (const key in responseData) {
const request = {
id: key,
artistId: artistId,
userEmail: responseData[key].userEmail,
message: responseData[key].message
};
requests.push(request);
}
context.commit('setRequests', requests);
},
};
I'm trying to set up a button that will delete the selected request object.
Your code is sending a POST request, which tells Firebase to generate a unique key. From the documentation on saving data:
POST: Add to a list of data in our Firebase database. Every time we send a POST request, the Firebase client generates a unique key, like fireblog/users/<unique-id>/<data>
The delete a node, send the DELETE verb/method to that path:
const response = await fetch(`https://find-artist-d3495-default-rtdb.firebaseio.com/requests/${payload.artistId}.json`, {
method: 'DELETE'
});
I am trying to use data from the client, which they would type into an input box. The idea is to use this for finding in my database to pull the data with the same username. on my Mongo DB:Atlas collection.
So its to use it like this to get the names from the database, .find({"username": request.body})
However, I keep getting the error "CastError: Cast to string failed for value "{ username: '' }" (type Object) at path "username" for model "Db1" on my terminal.
But when I try to hard code it onto the .find({"username": "name"), it works fine. Does anyone have any ideas?
**Javascript app**
async function pullData () {
let clientQ = document.querySelector('#userDB').value;
let entry = {
'username':clientQ
};
const options = {
method: "POST",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(entry)
};
const getData = await fetch('/database', options);
const request = await getData.json();
console.log(request);
};
```
-----------------------------------------------------
**Node Server**
app.post('/database', (request,response) => {
const info = request.body;
postModel.find({"username": info}, (error,data) => {
if(error){
console.log(error);
} else {
response.json(data);
}
});
});
----------------------------------------------
***client side DB***
async function pullData () {
let clientQ = document.querySelector('#userDB').value;
let entry = {
'username':clientQ
};
const options = {
method: "POST",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(entry)
};
const getData = await fetch('/database', options);
const request = await getData.json();
console.log(request);
Actually, you're passing the object {username : "value"} to the find method. You need to pass the string.
app.post('/database', (request,response) => {
const info = request.body; // object {username : "value"}
const username = info.username; // the string to search by username
postModel.find({"username": username}, (error,data) => {
if(error){
console.log(error);
} else {
response.json(data);
}
});
});
I have a pretty straight forward post request using axios.
I have played around with JSON.stringfy, adjusted my try/catch statement, and played around with various headers. No luck.
After doing some reading I think it has to do with the fact that I am not (req, res) anywhere. Thus, the lamda function returns undefined but the post request still works.
Just looking for a direction to go in because I am lost with how to implement (req,res).
const axios = require("axios");
// Declare spreadsheet and values to append
const spreadsheetId = "SECRET";
// build data for a POST request
const baseUrl = "https://pushtogsheet.herokuapp.com";
const query = `SECRET`;
const url = new URL(
`/proxy/google-sheets/${spreadsheetId}/values/A1:append?${query}`,
baseUrl
);
module.exports.handler = async (event, context) => {
try {
const dataHanlder = event.body;
const data = await JSON.parse(dataHanlder);
const {
firstName,
lastName,
email,
company,
empRange,
phone,
leadCountry,
signupType,
timezone,
utmSource,
utmMedium,
utmCampaign,
utmTerm,
utmContent,
} = data;
const excelArray = [
[
firstName,
lastName,
email,
company,
phone,
empRange,
timezone,
leadCountry,
signupType,
utmSource,
utmMedium,
utmCampaign,
utmTerm,
utmContent,
],
];
const excelString = await JSON.stringify({ values: excelArray });
const config = {
headers: {
"Pizzly-Auth-Id": "SECRET",
// "Content-Type": "text/plain",
},
};
const res = axios.post(url.href, excelString, config);
console.log("POST request status code", res.status);
} catch (error) {
console.log(error);
}
};
I have been trying to make a getItem request in an async Lambda function to dynamo DB, and I am not receiving any response at all. Any troubleshooting or help would be greatly appreciated.
in general, I am trying to make a request to a dynamodb table using the AWS SDK getItem, however, when I run my code there is no response for the await ddb.getItem function
so I am kinda lost as to what could be causing this.
// Load AWS SDK
const AWS = require("aws-sdk");
// Set the region
AWS.config.update({ region: "us-east-1" });
// Create the DyanmoDB service object
const ddb = new AWS.DynamoDB({ apiVersion: "2012-08-10" });
const handler = async (
event,
context,
callback,
test = false,
testObjFunc = {
test: () => {
Error("Testing enabled");
}
}
) => {
const response = {
isBase64Encoded: false,
statusCode: 200,
headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" },
multiValueHeaders: {},
body: JSON.stringify({ responseBody })
};
try {
// Parameters for DynamodDB getItem call
const dbParams = {
TableName: "Table_Name",
Key: {
personID: { S: "value" }
},
ProjectionExpression: "value_to_return"
};
// DynamoDB call to check for item
const results = await ddb.getItem(dbParams).promise();
console.log("success");
console.log(results);
} catch (error) {
response.statusCode = 500;
}
return response;
};
module.exports.handler = handler;
You have put the getitem call in try block, as you are not receiving any response means something is gone wrong in the try block.
please help I don't know what is wrong with my code.
Endpoints that doesn't need signature work fine, so I guess is a problem with how I am getting the signature. I am getting this error:
data: { code: -2014, msg: 'API-key format invalid.' } } }
API Doc: https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md
SIGNED endpoints require an additional parameter, signature, to be
sent in the query string or request body. Endpoints use HMAC SHA256
signatures. The HMAC SHA256 signature is a keyed HMAC SHA256
operation. Use your secretKey as the key and totalParams as the value
for the HMAC operation. The signature is not case sensitive.
totalParams is defined as the query string concatenated with the
request body.
My code:
const axios = require('axios');
const crypto = require('crypto');
const qs = require('qs');
const binanceConfig = {
API_KEY: 'XXXXXXX',
API_SECRET: 'XXXXXX',
HOST_URL: 'https://api.binance.com',
};
const buildSign = (data, config) => {
return crypto.createHmac('sha256', config.API_SECRET).update(data).digest('hex');
};
const privateRequest = async (data, endPoint, type) => {
const dataQueryString = qs.stringify(data);
const signature = buildSign(dataQueryString, binanceConfig);
const requestConfig = {
method: type,
url: binanceConfig.HOST_URL + endPoint + '?' + dataQueryString + '&signature=' + signature,
headers: {
'Authorization': `X-MBX-APIKEY: ${binanceConfig.API_KEY}`,
},
};
try {
console.log('URL: ', requestConfig.url);
const response = await axios(requestConfig);
console.log(response);
return response;
}
catch (err) {
console.log(err);
return err;
}
};
const data = {
symbol: 'ARKBTC',
recvWindow: 20000,
timestamp: Date.now(),
};
privateRequest(data, '/api/v3/openOrders', 'GET');
Try setting the headers object to have a key of X-MBX-APIKEY directly:
headers: {
'X-MBX-APIKEY': binanceConfig.API_KEY,
},