I have created an app using react-native.
After a little struggling I can now connect it to my Dynamodb table and using AWS Amplify I can insert items with PUT and get a specific item back with GET.
So far so good.
I now want to be able to query the table and get back a subset of records. The aws documentation suggests using aws-sdk and that the syntax should be like this:
// Return all of the songs by an artist, with a particular word in the title...
// ...but only if the price is less than 1.00
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SQLtoNoSQL.ReadData.Query.html
{
TableName: "Music",
KeyConditionExpression: "Artist = :a and contains(SongTitle, :t)",
FilterExpression: "price < :p",
ExpressionAttributeValues: {
":a": "No One You Know",
":t": "Today",
":p": 1.00
}
}
Is there a way that I can do this sort of query using Amplify?
For info: I setup the app and its API like this:
create-react-native-app dbapp
cd dbapp
aws mobile init
npm install aws-amplify --save
awsmobile cloud-api enable --prompt
Thanks,
@TheRealRed7 You can do this a few different ways.
awsmobile init
and enable cloud-logic, you would get a default backend lambda function that you could then include and query dynamo. You can see an example of something similar to that here:with Amplfiy / CLI this is basically:
$ awsmobile features
Select database and cloud-api (as you noted) then awsmobile push
to update your back-end. Then edit your awsmobilejs/backend lambda javascript file.
For this you'd just pass through and call the queries directly on the underlying aws-sdk, utilizing Amplify for the Auth portion (just make sure your auth role has permissions to query dynamodb table):
https://aws.github.io/aws-amplify/media/quick_start#working-with-aws-service-interface-objects
So for example:
import DynamoDB from 'aws-sdk/clients/dynamodb';
...
Auth.currentCredentials()
.then(credentials => {
const db= new DynamoDB.DocumentClient({
credentials: Auth.essentialCredentials(credentials)
});
// now you can run queries with dynamo and current scoped credentials i.e. db.query(...)
})
Thank you, I was really stuck with that.
Always nice to have choices - I chose option 2:
// Initialize the Amazon Cognito credentials provider
AWS.config.region = 'eu-west-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'eu-west-1:5f7af6b8-c701-4b54-a1ec-blahblahblah',
});
//I needed this to stop CRC errors (not too sure why they happened)
AWS.config.update({
dynamoDbCrc32: false
});
//create the db object
const db = new AWS.DynamoDB.DocumentClient({
apiVersion: '2012-08-10'
});
// setup the query params
var params = {
TableName : "blahblahprojectv-mobilehub-1547222168-blah blahblah",
ProjectionExpression:"hub_id, details.on_time, details.sensor_name",
KeyConditionExpression: "hub_id = :hid",
ExpressionAttributeValues: {
":hid":"PG2018f"
}
};
//then execute using db to query the dynamoDB table
db.query(params, function(err, data) {
if (err) {
console.log("Unable to query. Error:", JSON.stringify(err, null, 2));
} else {
console.log("Query succeeded.");
data.Items.forEach(function(details) {
console.log(details.hub_id,details.sensor_name);
//this is where I will populate the variables in my app
});
}
});
}
Thank you, I was really stuck with that.
Always nice to have choices - I chose option 2:
// Initialize the Amazon Cognito credentials provider
AWS.config.region = 'eu-west-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'eu-west-1:5f7af6b8-c701-4b54-a1ec-blahblahblah',
});//I needed this to stop CRC errors (not too sure why they happened)
AWS.config.update({
dynamoDbCrc32: false
});//create the db object
const db = new AWS.DynamoDB.DocumentClient({
apiVersion: '2012-08-10'
});// setup the query params
var params = {
TableName : "blahblahprojectv-mobilehub-1547222168-blah blahblah",
ProjectionExpression:"hub_id, details.on_time, details.sensor_name",
KeyConditionExpression: "hub_id = :hid",
ExpressionAttributeValues: {
":hid":"PG2018f"
}
};//then execute using db to query the dynamoDB table
db.query(params, function(err, data) {
if (err) {
console.log("Unable to query. Error:", JSON.stringify(err, null, 2));
} else {
console.log("Query succeeded.");
data.Items.forEach(function(details) {
console.log(details.hub_id,details.sensor_name);
//this is where I will populate the variables in my app
});
}
});
}
Hi ,
I am having an issue.. I am trying to do the same thing.
But , when I am querying from React JS code , request seems to be going on forever.
I have listed the issue here : https://github.com/aws-amplify/amplify-js/issues/2056
Can you please help me with this issue ?
Most helpful comment
@TheRealRed7 You can do this a few different ways.
This would be the most secure way, with the most "overhead" in terms of back-end. When you bootstrap using
awsmobile init
and enable cloud-logic, you would get a default backend lambda function that you could then include and query dynamo. You can see an example of something similar to that here:https://github.com/aws-samples/aws-serverless-ember/blob/master/cloud/index.js
with Amplfiy / CLI this is basically:
Select database and cloud-api (as you noted) then
awsmobile push
to update your back-end. Then edit your awsmobilejs/backend lambda javascript file.https://github.com/aws-samples/aws-mobilehub-ember/blob/master/app/adapters/note.js
For this you'd just pass through and call the queries directly on the underlying aws-sdk, utilizing Amplify for the Auth portion (just make sure your auth role has permissions to query dynamodb table):
https://aws.github.io/aws-amplify/media/quick_start#working-with-aws-service-interface-objects
So for example: