I am very new to Firebase and JS itself as well, and it is not the easiest thing to understand.
So, I have a Firebase real time databse set up with dummy "users" profiles, that each contain different properties.
i am trying to call user's properties.
I have managed to achieved it with the following approach:
let installDateRef = database.ref(`users/${userAccount}/installationDate`);
let lastUsedDateRef = database.ref(`users/${userAccount}/lastUsed`);
installDateRef.on('value', function(snapshot) {
installationDate.innerText = (snapshot.val());
}, function (error) {
installationDate.innerText = `Error: ${error.code}`
});
lastUsedDateRef.on('value', function(snapshot) {
lastUsedDate.innerText = (snapshot.val());
}, function (error) {
lastUsedDate.innerText = `Error: ${error.code}`
});
But in my application I want to display all of the user information, so copying this ".on" function seems like overkill.
Someone said that there is cleaner approach like this below
const firebasePromises = [
database.ref(`users/${userAccount}/installationDate`),
database.ref(`users/${userAccount}/lastUsed`)
];
Promise.all(firebasePromises).then(([_installationDate, _lastUsed]) => {
installationDate.innerText = (_installationDate.val());
lastUsedDate.innerText = (_lastUsed.val());
})
But I honest to God cannot make it work. It either returns undefined or returns array of my promises const.
.val() does not work at all even, saying that this is not a function.
Any help would on the best and working practice would be soooo much appreciated.
Thank you
#Doug Stevenson thank you! This is exactly what was needed:
const firebasePromises = [
database.ref(`users/${userAccount}/installationDate`).once('value'),
database.ref(`users/${userAccount}/lastUsed`).once('value'),
];
Promise.all(firebasePromises).then(snap => {
installationDateHTML.innerText = snap[0].val();
lastUsedDateHTML.innerText = snap[1].val();
})
Related
In my programming in Node.JS I made some code that worked, but I want to understand the concept of how it works.
In the code in question I use knex to retrieve information from a MySQL database. I import the knex module for that:
const config = {...}
const knex = require('knex')(config)
So far nothing new, only this time I needed to do a nested query and it was the first time. In this case, I consulted the sales data and then the sale items. I did it as follows:
const getSales = async () => {
await knex("tbl_vendas")
.select(knex.raw("tbl_vendas.id_vendas, tbl_vendedores.nome AS vendedor, " +
"tbl_clientes.nome_razaosocial AS cliente, tbl_vendas.data, tbl_vendas.hora, " +
"tbl_vendas.cupom, tbl_vendas.total"))
.leftOuterJoin("tbl_vendedores", "tbl_vendedores.id_vendedores", "tbl_vendas.id_vendedores")
.leftOuterJoin("tbl_clientes", "tbl_clientes.id_clientes", "tbl_vendas.id_clientes")
.then(sales => {
const rows = sales.map(sale => {
return knex("tbl_vendas_itens")
.select("tbl_vendas_itens.id_vendas_itens AS id_item", "tbl_produtos.descricao",
"tbl_vendas_itens.qtde", "tbl_vendas_itens.vl_unitario", "tbl_vendas_itens.desconto",
"tbl_vendas_itens.vl_total")
.leftOuterJoin("tbl_produtos", "tbl_vendas_itens.id_produtos", "tbl_produtos.id_produtos")
.where("tbl_vendas_itens.id_vendas", "=", sale.id_vendas)
.then(sales_items => {
const newRow = { ...sale, itens: [...sales_items] }
return newRow
})
})
return Promise.all(rows)
})
.then(console.log);
}
Writing this code was pretty intuitive and it worked, but then I was amazed that I used the knex constant twice, one inside the other, and it didn't hurt.
I ran a console.log(typeof(knex)) to find out what it was and it returned that it is a function.
Could someone explain the theory behind the use of knex inside the other and help me understand why it is okay to do this?
I am trying to learn Firebase. I made a very simple ReactApp along with a very simple database in Firebase. I am so beyond confused as to how to access a field's value. I'm sure this is an extremely simple question, but somehow, I am missing how to find the solution.
My database looks as such:
https://imgur.com/a/3LczlwI
I really would like to know how to access the "Speed" field value.
I have tried
const db = firebase.database.ref();
const speedRef =
db.child('react').child('mySpeed').once('value').then(snap =>{
if (snap.val()){
this.setState({ speed: snap.val().speed });
} else {
console.log('error');
}
})
Along with
const speedRef = firebase.database().ref().child('mySpeed').child('speed');
speedRef.on('value', snap => {
this.setState({ speed: snap.val() });
})
To no avail. I really hope someone can help me understand this. Thank you in advance.
*try to use this: *
const react = firebase.database().ref("react");
react.child("mySpeed").child("speed").once("value").then(data => {
if(data.val() !== null){
console.log(data.val());
}
});
I'm starting to learn firebase with firestore.
I have spent more hours than I would've like understanding the reference type and trying to get it to work with a simple query that references a portfolio's category.
This is the code:
try {
const portfolioSnap = await db.collection("portfolio").get();
let portfolioDoc = portfolioSnap.docs;
let categoriesRef = [];
portfolioDoc.forEach(p => {
categoriesRef.push(p.data().category.get());
});
let categories = await Promise.all(categoriesRef);
let portfolio = [];
portfolioDoc.map((p, i) => {
let portfolioObject = {
...p.data(),
category: categories[i].data().name
};
portfolio.push(portfolioObject);
});
return portfolio;
} catch (error) {
console.warn("ERROR: ", error);
}
I'm not sure if this makes sense.
I'm trying to get the category for each portfolio document but I feel this is over-engineered or I'm totally doing it the wrong way.
And this is not counting if I have references for images or files which I feel would make things... well, not pretty.
Nothing strange here. This is the way that nosql databases work (since there is no join operation, nor is there any explicit relationships between documents other than what you define).
exports.editData = functions.database.ref('/AllData/hello/A').onWrite((change, context) => {
const after = change.after;
if (after.exists()) {
const data = after.val();
var value = data;
// set of data to multiply by turns ratio
var actualEIn = (value.ein)*200;
console.log('Data Edited');
}
return admin.database().ref('/editedData/hello/A').push({
ein: actualEIn,
});
});
Edit: made some edits to the code as suggested! However, when I deploy it there are literally no logs.
Change this:
exports.editValues = functions.database.ref('/AllData/hello/A').onWrite((snapshot) => {
const data = snapshot.val();
if (data.exists()) {
into this:
exports.editValues = functions.database.ref('/AllData/hello/A').onWrite((change,context) => {
const data = change.after.val();
if (data.exists()) {
more info here:
https://firebase.google.com/docs/functions/beta-v1-diff#realtime-database
exports.editData = functions.database.ref('/AllData/hello/A/{id}').onWrite((change, context) => {
const afterData = change.after;
if (afterData.exists()) {
console.log('hey');
const data = afterData.val();
// set of data to multiply by turns ratio
var actualEIn = (data.ein)*200;
}
return admin.database().ref('/editedData/hello/A').push({
ein: actualEIn,
});
});
Hi guys thank you for all your help! :) I managed to solve this by adding a /{id} at the back!
You've got two things wrong here.
First, newer versions of the firebase-functions SDK since version 1.0 deliver a Change object to onWrite handlers instead of a snapshot, as it appears you are expecting. The Change object has properties for before and after with DataSnapshot objects of the contents of the database before and after the change that triggered the function. Please read the documentation for database triggers to get all the information.
Second, exists() is a method on DataSnapshot, but you're using it on the raw JavaScript object value of the contents of the database the location of change. JavaScript objects coming from val() will not have any methods to call.
You should probably update your code to:
Use the latest version of the firebase-functions module
Alter your function to accept the Change object instead of a snapshot
Use the exists() method on a snapshot in the change, rather than a raw JavaScript object.
Starter code:
exports.editValues = functions.database.ref('/AllData/hello/A').onWrite((change) => {
const after = change.after; // the DataSnapshot of the data after it was changed
if (after.exists()) {
const data = after.val() // the raw JavaScript value of the location
// use data here
}
})
I've been trying to fill an array with metadata that I collect with Xray, and haven't had any success. The function is called by an API route on my server and gets the links from my application.
I seem to be struggling with promises as it takes time to scrape the metadata, and I can't seem to get the function to wait until the data has been collected before moving on. Perhaps, I'm just not understanding how Xray works? Or maybe promises? I've tried everything I can think of, this being the most recent attempt (and the simplest):
function createCollection() {
Promise.all(rawLinks.map(function(link) {
linksArray.push(xray(link, 'title')(function(error, title) {
console.log(title);
return title;
}))
}))
.then(linksArray => {
console.log(linksArray);
});
}
It's by far not the most robust or elaborate solution I've tried, but it's the most recent one. First the console logs an array with "undefined" as the data, THEN it logs the individual titles.
I would be very thankful for any help, or direction on what to research. Like I've said, I feel as if I've exhausted all my ideas and don't know where to even look anymore.
Figured it out, this seems to be doing the trick!
// format links into an array of objects
var rawLinks = links.split(', ');
var linksArray = [];
createCollection();
function createCollection() {
rawLinks.map(function(link) {
var fillMetaPromise = new Promise(
function(resolve, reject) {
var test = xray(link, 'title')(function(err, title) {
var data = { title: title, link: link };
resolve(data);
});
})
.then(data => {
processTitle(data.title, data.link);
});
});
}
function processTitle(title, link) {
var object = {
link: link,
title: title
};
linksArray.push(object);
console.log(linksArray);
}