Fetching and displaying data from Firebase takes time - javascript

I'm reading value of pid from Firebase database and then using this pid value, I'm fetching further values from the database.
//fetching pid
firebaseRef.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
//getting key of the child
var pid = childSnapshot.key;
// childData will be the actual contents of the child
var childData = childSnapshot.val();
pid[i].id = "pid" + (i + 1);
document.getElementById(pids[i].id).innerText = pid;
i++;
});
});
//displaying marks
var pid1 = document.getElementById("pid1").innerHTML;
guideRef = firebase.database().ref("internal").child(pid1).child("guide");
guideRef.child("report").once('value').then(function(snapshot) {
document.getElementById(reportGuideMarks).value = snapshot.val();
});
But runnning this code I get this error:
Uncaught Error: Firebase.child failed: First argument was an invalid path: "". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"
The pid error is due to pid1 being null. But when I put delay of 3 seconds on the 'displaying marks' part, the code runs perfectly.
The displaying marks executes even before the values of pid have been set.
It takes a few seconds to set the value of pid in the table.
What is the issue? Why does it take so much time to load values of database? Or is it an issue with setting the value?

Requests to firebase are asynchronous so the "displaying marks" code will run before the "fetching pid" code has completed.
You could add another then() so the second part won't run until the first part has completed
//fetching pid
firebaseRef.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
//getting key of the child
var pid = childSnapshot.key;
// childData will be the actual contents of the child
var childData = childSnapshot.val();
pid[i].id = "pid" + (i + 1);
document.getElementById(pids[i].id).innerText = pid;
i++;
});
})
// new then() won't fire until prior then() is completed
.then(function() {
//displaying marks
var pid1 = document.getElementById("pid1").innerHTML;
guideRef = firebase.database().ref("internal").child(pid1).child("guide");
guideRef.child("report").once('value').then(function(snapshot) {
document.getElementById(reportGuideMarks).value = snapshot.val();
});
})

Related

Trying to limit my results and sort my data, from MongoDB using NodeJS

I am using MongoDB and Node.JS, I am trying to get data out of my MongoDB and show into my html page which I have working with the below code however this just brings back ALL entries in no particular order:
server.js
// This is for getting the list of all players from my DB
app.get("/getPlayers", function(request, response) {
db.getPlayers().then(function(players){
console.log(players);
response.send(players);
});
});
leadership.html
<script>
$(function() {
$.get("http://localhost:9000/getPlayers", {}, function (res) {
let data = res;
console.log(res);
for (i = 0; i < data.length; i++) {
let name = data[i].name;
let score = data[i].score;
console.log(data[i].name);
$("#leadership").append("<tr><td class=\"name\">"
+ data[i].name + "</td><td class=\"score\">"
+ data[i].score + "</td></tr>");
}
});
});
</script>
After looking at W3 Schools I tried to alter the code to this:
db.getPlayers().sort().limit(10).then(function(players)
However my Chrome console brings back an internal server error 500. Can someone point out how I can sort by LARGEST NUMBER first, then LIMIT the results to say 10? Within the database there is a collection called players, which holds name and score
db.js
var Player = mongoose.model("Player", {name: String, score: Number});
module.exports.Player = Player;
Try something like this.
Order, sort and limit can be passed from front end or change default values after : mark.
Players is imported model, you can do it this way or use method in the model itself.
app.post('/api/players',(req,res)=>{
let order = req.body.order ? req.body.order : "-1";
let sortBy = req.body.sortBy ? req.body.sortBy : "_id";
let limit = req.body.limit ? parseInt(req.body.limit) : 100;
Players.
find().
sort([[sortBy,order]]).
limit(limit).
exec((err,players)=>{
if(err) return res.status(400).send(err);
res.status(200).json({
size: players.length,
players
})
})
})

How to remove data from firebase?

I am having trouble removing data from my database on Firebase. I am able to remove data but when I remove the data its removing all my users? I only wanted it to remove the user represented in the user ID.
My JS
function removeUser(userID){
var userRef = firebase.database().ref('users/');
// Returned no user found
//var userRef = firebase.database().ref('users/').child('userID');
// Returned reference child error
//var userRef = firebase.database().ref('users/').child(userID);
userRef.once('value', function(snapshot) {
if (snapshot.val() === null) {
alert("no user found");
}else{
userRef.ref.remove();
}
});
console.log('Remove Success');
}
document.getElementById('removeUserBtn').addEventListener('click', function(){
removeUser(userID);
});
You need to specify the full path to the child you are trying to remove:
var childUserRef = firebase.database().ref(`users/${userId}`)
and call the .remove() method as in : childUserRef.remove()
More details:
https://firebase.google.com/docs/reference/js/firebase.database.Reference

web based firebase code running multiple times when executed

I am trying to update some data into my Firebase realtime database, but for some reason the code runs multiple times when i present it with a new string, this messes up the output of the code.
Below is what I have tried, I tried to create a new function for the ref.update(), but the same thing happens again, I have pointed in the comments of the code where exactly the code goes back to.
function fire_base_db() {
var ref = firebase.database().ref();
ref.on("value", function(snapshot) {
r = snapshot.val();
var ham_db = r.hams.spam_words;
var spam_db = r.spams.spam_words; //contains spam data now
console.log('function 1')
inputstring(ham_db, spam_db);
}, function(error) {
console.log("Error: " + error.code);
});
}
inputstring(ham_db, spam_db); //just a random function i need
spam_prop(user_string_toknized, spam_db, ham_db); //yet another
function spam_or_ham()
function spam_or_ham() {
var final_value = " ";
if (total_spam_probablity < total_ham_probablity) {
console.log("ham");
final_value = "ham";
} else {
console.log("spam");
final_value = "spam";
}
if (final_value = "spam") {
var ref = firebase.database().ref("hams/spam_words/");
ref.update(old_words_spam_2);
} else if (final_value = "ham") {
var ref2 = firebase.database().ref("spams/spam_words/")
ref2.update(old_words_ham_2)
};
for (var a in new_words_spam) {
new_words_spam[b] = 1
}
for (var b in new_words_ham) {
new_words_ham[a] = 1;
}
if (final_value = "spam") {
var ref9 = firebase.database().ref("spams/spam_words/")
ref9.update(new_words_spam)
} else if (final_value = "ham") {
var ref2 = firebase.database().ref("hams/spam_words")
ref2.update(new_words_ham)
}
}
fire_base_db_upadt_new_words();
fire_base_db_upadt_new_words_2();
The first function fire_base_db() is used to read data from the database, the next 2 functions are just some steps for the output, the last function spam_or_ham is where the bug appears, moment the code enters the if statement and reaches the ref9.update part, it runs back to ref.on in the first function and run multiple times, each time executing till the ref9 part, except in the last execution where the whole code is executed, I want the full code to be executed in the first time itself.

Sequelize transaction stops executing during loop

I am trying to do a transaction that loops through multiple items and inserts them into the database. If i just have 1 item in each array, the code executes fine, it inserts the deployment, the crew and the equipment. However if I have 2 or more items in either equipment or crew, the application just freezes, no error or anything.
The console output looks like this:
Executing (e337b7de-e95f-4d18-a2e9-1216cb8b7d61): START TRANSACTION;
----------------------CREATE DEPLOYMENT---------------
Executing (e337b7de-e95f-4d18-a2e9-1216cb8b7d61): INSERT INTO `deployments` (`id
`,`dateDeployed`,`dateReturned`,`city`,`province`,`country`,`fireName`,`fireNumb
er`,`fireCenter`,`unitNumber`,`comments`,`finalSold`,`status`,`createdAt`,`updat
edAt`,`contractId`,`deploymentTypeId`,`productId`) VALUES (DEFAULT,'2018-03-01',
'Invalid date','1','BC','CAN','1','1','1','1','test','','active','2018-03-08 22:
36:44','2018-03-08 22:36:44','5','1','1');
----------------------CREATE EQUIPEMENT---------------
----------------------CREATE EQUIPEMENT---------------
Executing (default): INSERT INTO `deploymentEquipments` (`createdAt`,`updatedAt`
,`deploymentId`,`equipmentId`) VALUES ('2018-03-08 18:09:31','2018-03-08 22:36:4
4',17,1);
Executing (default): INSERT INTO `deploymentEquipments` (`createdAt`,`updatedAt`
,`deploymentId`,`equipmentId`) VALUES ('2018-03-08 18:09:39','2018-03-08 22:36:4
4',17,2);
My code is like this:
app.post('/deployment', function(req,res,next){
var deployment = req.body;
var crew = req.body.deploymentCrew;
var equipment = req.body.deploymentEquipment;
var deploymentId = "";
//insert new deployment - start transaction, add deployment, get ID, loop through crew, loop through equipment
models.sequelize.transaction(t =>
{
var equipPromises = [];
console.log('----------------------CREATE DEPLOYMENT---------------');
return models.deployment.create(req.body, {transaction: t})
.then(function(newDeployment) {
deploymentId = newDeployment.dataValues.id;
for (var i = 0; i < equipment.length; i++) {
console.log('----------------------CREATE EQUIPEMENT---------------');
var equip = equipment[i];
equip.deploymentId = deploymentId;
equip.equipmentId = equipment[i].id;
var equipPromise = models.deploymentEquipment.create(equip, equipPromises.push(equipPromise));
}
return Promise.all(equipPromises);
})
.then(function() {
console.log('----------------------CREATE STAFF---------------');
var crewPromises = [];
for (var i = 0; i < crew.length; i++) {
var staff = crew[i];
staff.deploymentId = deploymentId;
staff.staffId = crew[i].staff.id;
var crewPromise = models.deploymentCrew.create(staff, crewPromises.push(crewPromise));
}
return Promise.all(crewPromises);
});
}).then(result => {
console.log('deployment added');
res.send(result);
}).catch(err => {
console.log('deployment creation failed');
res.status(401).send({'message':err, 'redirect': '/'});
});
});
Any thought's or ideas why this might be happening would be appreciated.
Thanks
It was actually quite simple, I wasn't adding the transaction into the looped create statements. So now it is like:
//this is the old statement
//var equipPromise = models.deploymentEquipment.create(equip, equipPromises.push(equipPromise));
//this is the new correct way to do it
equipPromises.push(models.deploymentEquipment.create(equip, {transaction:t}));

how to display firebase val on a html like counter with javascript

I'm training do display the current value from my firebase database
on to my HTML counter.
the problem is that I see only the current clicks and not the total clicks
in the console, I can see the database value + 1
var bunnyData = null;
function thumbsUpBtn(val) {
var count = document.getElementById('like').value;
var new_count = parseInt(count ,10) + val;
if (new_count < 0) {
new_count = 0;
}
var videosList = firebase.database().ref().child('videos');
videosList.on("value", function(snapshot) {
var allVideos = snapshot.val();
bunnyData = allVideos.bunny;
console.log( bunnyData.likeCount);
WriteStatsToPage();
});
onclick
videosList.child("bunny").set({
likeCount : bunnyData.likeCount+1,
dislikeCount : bunnyData.dislikeCount,
viewsCount : 100
});
function WriteStatsToPage(){
$("likeNUmber").html[bunnyData.likeCount];
}
document.getElementById('like').value = new_count ;
return new_count ;
}
<button id="thumbsUp" onClick="thumbsUpBtn(1)">
<img class="likeImg" src="Like.png" >
<input id="like" value="0" ></button>
Transactions and Batched Writes
Transactions are useful when you want to update a field's value based
on its current value, or the value of some other field. You could
increment a counter by creating a transaction that reads the current
value of the counter, increments it, and writes the new value to Cloud
Firestore.
A transaction consists of any number of get() operations followed by
any number of write operations such as set(), update(), or delete().
In the case of a concurrent edit, Cloud Firestore runs the entire
transaction again. For example, if a transaction reads documents and
another client modifies any of those documents, Cloud Firestore
retries the transaction. This feature ensures that the transaction
runs on up-to-date and consistent data.
// Create a reference to the SF doc.
var sfDocRef = db.collection("cities").doc("SF");
// Uncomment to initialize the doc.
// sfDocRef.set({ population: 0 });
return db.runTransaction(function(transaction) {
// This code may get re-run multiple times if there are conflicts.
return transaction.get(sfDocRef).then(function(sfDoc) {
var newPopulation = sfDoc.data().population + 1;
transaction.update(sfDocRef, { population: newPopulation });
});
}).then(function() {
console.log("Transaction successfully committed!");
}).catch(function(error) {
console.log("Transaction failed: ", error);
});

Categories

Resources