How to pass variable key value in dynamodb - amazon-dynamodb

Am trying to get the items from DynamoDB table based on the current date. Using the date value in string format when am trying to run the below piece of code, its error out saying:
{
"errorMessage": "ERROR: Dynamo failed: TypeError: Cannot read property 'datatype' of undefined"
}
Below is the piece of code:
exports.handler = function(event, context) {
console.log("Request received:\n", JSON.stringify(event));
console.log("Context received:\n", JSON.stringify(context));
var doc = require('dynamodb-doc');
var dynamodb = new doc.DynamoDB();
var params = {
Key: {
"abc" : datetime1
},
TableName: 'myTable',
ProjectionExpression: 'message'
};
var Message = callback();
var datetiem = new Date().toISOString().split('T')[0];
console.log('date is ', datetiem); // prints 2018-01-09
var datetime1 = JSON.stringify(datetiem);
console.log(datetime1); //prints "2018-01-09"
function callback (message) {
dynamodb.getItem(params, function (err, data) {
if (err) {
context.fail('ERROR: Dynamo failed: ' + err);
} else {
console.log('Dynamo Success: ' + JSON.stringify(data, null, ' '));
console.log('data', data)
let Message = data['Item'].message;
console.log('test',Message);
}
});
}
};
It runs fine if I pass the value directly i.e. "abc" : "2018-01-09"
Can someone please advice?

I'm not sure your datetime1 variable is defined when you use it in parameters. Try this:
exports.handler = function(event, context) {
console.log("Request received:\n", JSON.stringify(event));
console.log("Context received:\n", JSON.stringify(context));
var doc = require('dynamodb-doc');
var dynamodb = new doc.DynamoDB();
var Message = callback();
var datetiem = new Date().toISOString().split('T')[0];
console.log('date is ', datetiem); // prints 2018-01-09
var datetime1 = JSON.stringify(datetiem);
console.log(datetime1); //prints "2018-01-09"
var params = {
Key: {
"abc" : datetime1
},
TableName: 'myTable',
ProjectionExpression: 'message'
};
function callback (message) {
dynamodb.getItem(params, function (err, data) {
if (err) {
context.fail('ERROR: Dynamo failed: ' + err);
} else {
console.log('Dynamo Success: ' + JSON.stringify(data, null, ' '));
console.log('data', data)
let Message = data['Item'].message;
console.log('test',Message);
}
});
}
};

Related

How to check if the emaiID exists or not in the dynamodb?

am using node js for the lambda function. I need to check whether the emailID exists or not in the dynamo db...If the emailID exists it should prompt to the user that emailid already exists if not it should store the values in the dynamo db ....
EmailID is the sort key
Customername is the primary key
How can i do that ..
Below is my code:
var doc = require('aws-sdk');
var dynamodb = new doc.DynamoDB()
var tableName = "Testing";
exports.handler = (event, context, callback) => {
var EmailID = event.EmailID; // or any other var which is having emaiID
console.log(event)
var params = {
TableName: "Testing",
Key: { EmailID : "abc#gmail.com",
CustomerName : "ABC"},
AttributeUpdates: {
verified: {
Action: "PUT",
Value: true
}
}
};
// Update the user.
dynamodb.update(params, function(err, data)
{
if (err)
{
console.log(JSON.stringify(err));
context.fail(JSON.stringify(err));
return;
}
context.succeed("User successfully updated.");
});
putItem
var AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();
exports.handler = (event, context, callback) => {
// TODO implement
var tableName = "Testing";
console.log(event.EmailID)
var parms = {
TableName : tableName,
Item : {
"EmailID" : event.EmailID,
"CustomerName" : event.CustomerName,
"PersonName" : event.PersonName,
"EmailSent" : event.EmailSent,
"Password" : event.Password
}
};
docClient.put(parms, function(err, data)
{
if (err){
callback(err)
}
else
{
callback(null,"Successfully updated data!!!")
}
})
};
To achieve this I would use the Put operation and use the "exists" parameter. Setting it to false will make sure the put operation will fail if an item already exists. When there is no match then put will insert the record.
For more details on how to use this operation in javascript please check out the documentation:
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#putItem-property
So in your put example you could add the following to your params:
var AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();
exports.handler = (event, context, callback) => {
// TODO implement
var tableName = "Testing";
console.log(event.EmailID)
var parms = {
TableName: tableName,
Item: {
"EmailID": event.EmailID,
"CustomerName": event.CustomerName,
"PersonName": event.PersonName,
"EmailSent": event.EmailSent,
"Password": event.Password
},
ConditionExpression: "attribute_not_exists(EmailID)"
};
docClient.put(parms, function (err, data) {
if (err) {
callback(err)
}
else {
callback(null, "Successfully updated data!!!")
}
})
};

Firebase Cloud Functions - return undefined

This is the code that I am using to fetch the senderName and messageText from my database. In my logs, I am getting an error saying "Function returned undefined, expected Promise or value". I am using this function to send notifications to the recevier of the message. The notification is being sent appropriately.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendPushNotification = functions.database.ref('/messages/{messageId}').onWrite(event => {
var db = admin.database();
var messageText;
var senderName;
var receiverId;
var senderId;
var messageId = event.params.messageId;
var messageTextRef = db.ref('/messages/' + messageId + '/text');
var senderIdRef = db.ref('/messages/' + messageId + '/fromId');
var receiverIdRef = db.ref('/messages/' + messageId + '/toId');
messageTextRef.once("value", function(data) {
messageText = data.val();
senderIdRef.once("value", function(data) {
senderId = data.val();
receiverIdRef.once("value", function(data) {
receiverId = data.val();
var senderNameRef = db.ref('/users/' + senderId + '/name');
senderNameRef.once("value", function(data) {
senderName = data.val();
console.log(senderName);
console.log(messageText);
const payload = {
notification : {
title: String(senderName),
body: String(messageText),
badge: "1",
sound: 'default',
}
};
return admin.database().ref('fcmToken').once('value').then(allToken => {
if (allToken.val()) {
const token = Object.keys(allToken.val());
return admin.messaging().sendToTopic(receiverId, payload).then(response => {
});
};
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
});
});
You have a monster function there. If you return the outermost Promise when you are getting all the database values that should fix the issue, and also ensure that your function is not stopped before all computation is complete. In your case this is on line ~25:
...
return messageTextRef.once("value", function(data) {
...

Cordova SQLite class - cannot return value from database

So, I'm building an app with Cordova and SQLite and below is the object Storage I created to handle the database properties and methods.
function Storage(connection, platform)
{
if (platform == 'mobile') {
this.db = window.sqlitePlugin.openDatabase({name: connection.name, location: connection.location});
} else if (platform == 'web') {
this.db = window.openDatabase(connection.name, connection.version, connection.mode, -1);
}
this.read = function(sql, vals) {
var rows = null;
this.db.transaction(function(tx) {
tx.executeSql(sql, vals, function(tx, res) {
rows = res.rows;
});
}, function(error) {
console.log('Transaction error: '+error.message);
});
return rows;
};
};
var connection = {
name: 'database.db',
version: '1.0',
mode: 'Development'
};
var db = new Storage(connection, 'web');
var sql = '';
sql += 'SELECT *';
sql += ' FROM countdown';
sql += ' WHERE countdown_status != ?;';
var rows = db.read(sql, [1]);
console.log(rows);
This code logs 'null' and I don't know why since I have data into my database. And when I try to log from within the tx.executeSql method, it logs the data from database.
Any ideas on why I cannot get this data out of that function?
Thanks a lot.
the db read is asynchronous - it needs to return the data to a callback function like so:
getHighScore: function (type,callback) {
var query = "SELECT Value FROM HighScore where Type = '" + type + "';";
playedDb.transaction(function (tx) {
tx.executeSql(query, [], function (tx, res) {
var out;
if (typeof res.rows.item(0) === "undefined") {
if (typeof callback === "function") {
callback(-1);
return;
};
} else {
out = res.rows.item(0).Value
//task 301 only allow alphanumeric and decimal point (for version)
out = String(out).replace(/[^0-9a-z\.]/gi, '');
if (typeof callback === "function") {
callback(out);
return;
};
}
}, function (e) {
console.log("getHighScore FAILED: " + e.message);
if (typeof callback === "function") {
callback(-2);
return;
};
});

Firebase infinite loop insert my item on child_added/set

I got an infinite loop inserting an item to my Firebase, so when I click on my post form, it inserts my item until I kill the process. Can you help me how to solve it?
PS : I'm using VueJS
var usersRef = new Firebase('https://xxxxxxxxxxxxxxxxxx.firebaseio.com/userslist/');
var vm = new Vue({
el: '#list1',
data: function () {
return{
// Initialisation du tableau de users
users: [],
sortKey: 'id',
reverse: 1,
nextKey: null
};
},
ready: function () {
// this works
//this.sortKey = 'name';
},
methods: {
updateUsers: function () {
},
removeUser: function (item) {
usersRef.child(item.id).remove();
},
addItem: function (e) {
e.preventDefault();
// get form data as Json
var jsonData = ConvertFormToJSON('form_add');
//console.log(jsonData);//test ok
//get the last item id and save it to next key
usersRef.limitToLast(1).on('child_added', function (snapshot) {
var lastKey = parseInt(snapshot.key());
this.nextKey = lastKey + 1;
console.log('nextKey ' + nextKey);//test ok
//
// save data to firebase
usersRef.child(this.nextKey).set(jsonData, function (snap) {
//console.log('add success');//test
//Notification par Jquery
var itemAdded = snap.val();
$.notify(itemAdded.firstname + " " + itemAdded.name + " à été ajouté", "success", {position: "top right"});
this.pendingKey = 0;
});
});
},
// Tri des colonnes
sortBy: function (_sortKey) {
this.reverse = (this.reverse == -1) ? 1 : -1;
this.sortKey = _sortKey;
console.log("SortKey " + this.sortKey);
}
}
});
usersRef.on('child_added', function (snapshot) {
var item = snapshot.val();
item.id = snapshot.key();
console.log('id ' + item.id);
vm.users.push(item);
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
thanks for your help
OK I've found a solution :
//get the last item id and save it to next key
var _nextKey = this.nextKey;
usersRef.limitToLast(1).on('child_added', function (snapshot) {
var lastKey = parseInt(snapshot.key());
_nextKey = lastKey + 1;
});
this.nextKey = _nextKey;
console.log('nextKey ' + this.nextKey);//test ok
// save data to firebase
usersRef.child(this.nextKey).set(jsonData, function (snap) {
//console.log('add success');//test
//Notification par Jquery
var itemAdded = snap.val();
$.notify(itemAdded.firstname + " " + itemAdded.name + " à été ajouté", "success", {position: "top right"});
});
May it help someone!

how to push data back to client in meteor?

I have to make a aggregate query to DB when the user click on a button, however I don't know how to return that result back to the client since I'm doing an asynchronous request, this is part of my code:
//Server side
Meteor.startup(function() {
Meteor.methods({
getAllTotals: function (query){
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
var error = result = match = pipeline = '';
var group = {
$group: {
_id: null,
wall_clock: {
"$sum": "$wall_clock"
},
mem:{
"$sum": "$mem"
},
cpu:{
"$sum": "$cpu"
},
io:{
"$sum": "$io"
},
vmem:{
"$sum": "$vmem"
},
maxvmem:{
"$sum": "maxvmem"
}
}
};
if(typeof query.submission_time !== "undefined"){
match = {"$match": {submission_time: query.submission_time}};
pipeline = [match, group];
}else{
pipeline = [group];
}
db.collection("GE_qstat_job_monitor").aggregate(
pipeline,
Meteor.bindEnvironment(
function (error, result){
console.log(result); // <<--- this is OK!
},
function(error) {
Meteor._debug( "Error doing aggregation: " + error);
}
)
);
return result; // <<--- this is empty
}
});
}
any suggestion? :-)
Short answer:
Solution you can find here:
How to get an async data in a function with Meteor
Detailed answer
using Meteor._wrapAsync
var aggregateTotal = function(callback){
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
// ...
db.collection("GE_qstat_job_monitor").aggregate(
pipeline,
function (error, result){
if(error){
callback(error);
}else{
callback(null, result);
}
}
);
}
var aggregateTotalsSync = Meteor._wrapAsync(aggregateTotal);
Meteor.methods({
'getAllTotals': function(){
var result;
try{
result = aggregateTotalsSync();
}catch(e){
console.log("getAllTotals method returned error : " + e);
}finally{
return result;
}
}
});
using Futures (meteorPad example)
//Server side
Meteor.startup(function() {
var Future = Npm.require('fibers/future');
Meteor.methods({
getAllTotals: function (query){
var fut = new Future();
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
// ...
db.collection("GE_qstat_job_monitor").aggregate(
pipeline,
Meteor.bindEnvironment(
function (error, result){
if(error){
fut.throw(error);
}else{
fut.return(result)
}
},
function (exception){
// caught exception is passed to this callback
fut.throw(exception);
}
)
);
return fut.wait();
}
});
}
Easy but a bit dirty way (but not so much if you think well about your architecture) -> send back the result trough Mongo.
You can even do it without Meteor.methods, with the request creation inserted in the database on the client, an observer on the server that check it and does the async task, and then write back the result in the database.

Resources