Dynamodb record not updating through for loop - node.js

I'm currently using dynamoose for managing records in dynamodb.
from my client I'm receiving a collection of insiders
insiders: [
{ uid: '123', name: 'Insider A' },
{ uid: '456', name: 'Insider B' },
{ uid: '789', name: 'Insider B' }
]
and my lambda function receives the collection thru insiders variable and I loop in each records. Inside loop I update the position of the records
module.exports.reorder = async (event) => {
const klass = await getKlass.byEnv(process.env.STAGE, 'insider');
const req = event.body
var insiders = req.insiders;
try {
for (let [index, insider] of insiders.entries()) {
console.log("Insider: ", insider);
console.log("Index: ", index);
await klass.update({ uid: insider.uid }, {
$PUT: {
position: index += 1
}
}, { condition: 'attribute_exists(uid)' })
}
return successResponse.message();
} catch (err) {
console.log("===============");
console.error(err);
console.log("===============");
if (err && err.code == 'ConditionalCheckFailedException') {
return noRecord404.notFound();
}
}
}
this is working fine when I'm testing it in my local but when I deploy it to AWS Lambda It's not being updated. I also put console.log inside loop and I'm getting the printed log.

Related

Flutter notifications from firebase messaging is delayed?

sometime the notification is delayed for no reason and then comes all together iam using
https://pub.dev/packages/flutter_local_notifications
https://pub.dev/packages/firebase_messaging
here is my code from cloud functions ( nodejs )
exports.messageTrigger = functions.firestore.document('/Messages/{messageID}').onCreate(
async (snapshot, context) => {
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
var currentRoomUsers = snapshot.data().members;
currentRoomUsers.forEach( (userID) => {
db.collection('Users').doc(userID).get().then(async(doc)=>{
if(doc.exists && doc.id != snapshot.data().senderID){
const message = {
data: {
title: `New message from ${capitalizeFirstLetter(snapshot.data().room)}`,
body: snapshot.data().type == 'm.text' ? 'Sent a new message' : snapshot.data().type == 'm.start'? 'Invited you for a call' : snapshot.data().type == 'm.image' ? 'Sent an image' : 'Sent a new message'
},
tokens: doc.data()['Device_token'],
android: {
priority: 'high',
},
priority: "high",
}
await admin.messaging().sendMulticast(message);
}else {
console.log("No such document!");
}
}).catch((error)=>{
console.log("Error getting document:", error);
});
}
);
}
);
Firestore documents are fetched asynchronously and the sendMulticast() statement here may run before all the documents are fetched. Also, you must terminate Cloud Functions by returning a Promise. Since you are using an async function, try refactoring the code with async-await syntax as shown below:
exports.messageTrigger = functions.firestore
.document("/Messages/{messageID}")
.onCreate(async (snapshot, context) => {
try {
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
const currentRoomUsers = snapshot.data().members;
// use Promise.all() to fetch all documents
const customRoomUsersSnap = await Promise.all(
currentRoomUsers.map((user) =>
db.collection("Users").doc(user).get()
)
);
const messagePromises = [];
// Iterate over all documents and add a message for every existing document
customRoomUsersSnap.forEach((userSnap) => {
if (userSnap.exists) {
const message = {
data: {
title: `New message from ${capitalizeFirstLetter(
snapshot.data().room
)}`,
body:
snapshot.data().type == "m.text"
? "Sent a new message"
: snapshot.data().type == "m.start"
? "Invited you for a call"
: snapshot.data().type == "m.image"
? "Sent an image"
: "Sent a new message",
},
tokens: userSnap.data()["Device_token"],
android: {
priority: "high",
},
priority: "high",
};
messagePromises.push(admin.messaging().sendMulticast(message));
} else {
console.log(`User ${userSnap.ref.id} doc does not exist`);
}
});
// Send all messages simultaneously.
return Promise.all(messagePromises);
} catch (error) {
console.log(error);
// return Promise<null> in case of an error
return null;
}
});

setInterval() is not wotking in azure microsoft

setInterval() is not working in Azure Microsoft. I need a function to do the task every month or week? so what can I do? the code is working without azure but with azure not working?
nodejs code :
setInterval(async function check() {
if ((date.getDate() == 8) && (date.getHours() == 18) && (date.getMinutes() == 39) && (date.getSeconds() == 00)) {
await Drawings.find({}).then((data) => {
data.sort(function (a, b) {
return b.stars - a.stars;
})
if (data == null) {
return;
}
AllDrawings.updateMany({
"potmCurrentWinner": true
}, {
$set: {
"potmCurrentWinner": false
}
}, async function (err) {
if (err) {
return;
}
// move the drawing to potm
await AllDrawings.updateOne({
"DrawingName": data[0]['DrawingName']
}, {
$set: {
"potmCurrentWinner": true,
"potm": true
}
}, async function (err) {
//move file
await User.updateOne({
userName: data[0].Drawer
}, {
$inc: {
stars: 25
}
})
console.log("done3");
await User.updateOne({
userName: data[0].Drawer
}, {
$inc: {
drawingOfTheMonth: 1
}
});
//delete all drawwing the u give star
await User.updateMany({}, {
$set: {
drawingThatGotYourStar: []
}
});
await Drawings.deleteMany({});
console.log("done4");
});
});
})
you have missing code here, the brackets from the initial condition and the closing parenthesis for the setInterval function call

Sorting in mongoose

Alright, this is very wierd but the sort does not work. it does not throw any error but the sort does not work.
try {
properties = await Property.find({}).sort("-minimumPrice");
} catch (err) {
console.log(err)
}
I also tried but it didnt work as well:
try {
properties = await Property.find({}).sort({minimumPrice: "desc"});
} catch (err) {
console.log(err)
}
See here for some decent answers on sorting and
here is some good official docs on mongoose async/await
You should use .exec() with await for better stack traces, the sort can take these values: asc, desc, ascending, descending, 1, and -1.
try {
let properties = await Property.find(query).sort({"minimumPrice": -1}).exec()
} catch (err) {
console.log(err)
}
This is all assuming your query is correct and is retrieving documents to be sorted.
UPDATE
I went through your whole situation and created a test using what you provided.
const mongoose = require("mongoose");
var Schema = mongoose.Schema;
var propertySchema = new Schema({
name: String,
minimumPrice: Number
});
var Property = mongoose.model('Property', propertySchema);
//Testing
(async function() {
try {
//connect to mongo
await mongoose.connect('mongodb://localhost:27017/testing', { useNewUrlParser: true, useUnifiedTopology: true });
//First, delete all properties
await Property.deleteMany({}).exec();
let properties = [];
//Insert 5 properties
for (var i = 1; i < 6; i++) {
properties.push({ name: "property" + i, minimumPrice: Math.round(Math.random() * 10000) });
}
//Insert all our random properties
await Property.create(properties);
console.log(properties);
//Now, retrieve all our properties
let sortedProperties = await Property.find({}).sort({ minimumPrice: -1 }).exec();
console.log("sorted", sortedProperties);
} catch (err) {
console.log(err);
}
})();
Database Input:
[
{ name: 'property1', minimumPrice: 3846 },
{ name: 'property2', minimumPrice: 7910 },
{ name: 'property3', minimumPrice: 7234 },
{ name: 'property4', minimumPrice: 4444 },
{ name: 'property5', minimumPrice: 6366 }
]
Sorted Output:
[
{
name: 'property2',
minimumPrice: 7910
},
{
name: 'property3',
minimumPrice: 7234
},
{
name: 'property5',
minimumPrice: 6366
},
{
name: 'property4',
minimumPrice: 4444,
},
{
name: 'property1',
minimumPrice: 3846
}
]
You can see the properties come back sorted. Which leads me to assume, somewhere you've inserted your minimumPrice as a string.

Mongoose exec() does not await properly

For some reason, exec() is not awaiting in my code:
let team = <SOME TEAM NAME> //putting manually for testing
let results = []
TeamModel.find({ name: team })
.exec(async (err, docs) => {
if (err)
return res.send(Response("failure", "Error occured while retrieving fixtures"))
for(let i = 0; i < docs.length; i++){
let doesExist = await FixtureModel.exists({ leagueName: docs[i].leagueName })
if (doesExist) {
let query = FixtureModel.find({ leagueName: docs[i].leagueName, $or: [{ homeTeam: team }, { awayTeam: team }] })
await query.exec((err2, docs2) => {
if (err2)
return res.send(Response("failure", "Error occured while retrieving fixtures"))
docs2.forEach((doc2, index) => {results.push(doc2.toObject())})
console.log('during await') //Executes second
})
console.log('after await') //Executes first
}
else { //This section is not required
let result = await Communicator.GetFixturesFromLeague(docs[i].leagueId)
result.api.fixtures.forEach((fixture, index) => {
let newFixture = new FixtureModel({
fixtureId: fixture.fixture_id,
leagueId: fixture.league_id,
leagueName: fixture.league.name,
eventDate: fixture.event_date,
statusShort: fixture.statusShort,
homeTeam: fixture.homeTeam.team_name,
awayTeam: fixture.awayTeam.team_name
})
newFixture.save()
results.push(newFixture.toObject())
})
}
}
console.log(results)
res.send(Response("success", "Retrieved fixtures", results))
})
and the result looks something like this:
after await
[]
during await
and therefore an empty array of results is sent before values are added inside. I'm not sure what I'm missing here.
This is a workaround if anyones wondering. Sending the response inside the exec() callback when the forLoop completes bypassing the need for async/await.
if (doesExist) {
let query = FixtureModel.find({ league_name: docs[i].leagueName, $or: [{ homeTeam: { team_name: team} }, { awayTeam: { team_name: team} }] })
await query.exec((err2, docs2) => {
if (err2)
return res.send(Response("failure", "Error occured while retrieving fixtures"))
docs2.forEach((doc2, index) => {results.push(doc2.toObject())})
if(i + 1 == docs.length){
return res.send(Response("success", "Retrieved fixtures", results))
}
})
}

How to retrieve an object ID generated by Firebase?

I have the following object:
root: {
id1: { /* this is an autogenerated id by Firebase */
name1: "abc",
name2: "xyz"
},
id2: {
name1: "abc",
name2: "xyz"
},
id3: {
name1: "abc",
name2: "xyz"
},
}
My code to retrieve the whole snapshot is:
getRoot () {
firebase.database ().ref ('roots/')
.on('value', function (snapshot) {
console.log (snapshot.val());
})
}
Everything is perfect. I got every object from the root component, but I can't figure out how to access the IDs and their children? Thanks!
I didn't remember I posted this question. I found out how to do this long time ago.
Here is the code that will do the job:
Service:
myFunction () {
var ref = firebase.database ().ref ('roots')
return new Promise ((resolve, reject) => {
ref.on ('value', function (snapshot) {
if (snapshot.val () == null) {
reject (null);
} else {
var list = new Array ();
snapshot.forEach (function (data) {
var item = {
key: data.key, //this is to get the ID, if needed
name1: data.val ().name1,
name2: data.val ().name2,
}
list.push (item);
});
resolve (list);
}
});
});
}
Component:
this.myService.myFunction ().then (objects => {
this.objects = objects;
for (let obj of this.objects) {
console.log (obj.key);
}
}).catch (error => {
alert ('Nothing found');
})
Wish you a happy coding!

Resources