How to get value of node in firebase database in Cloud Function - javascript

exports.respublished =
functions.database.ref('/Posts/{postid}').onWrite(event => {
const snapshot = event.data;
const postid = event.params.examid;
const uid = snapshot.child('uid').val();
const ispublic = snapshot.child('Public').val();
firebase.database.ref('Users/' + uid).once(event => {
const snapshot = event.data;
const name = snapshot.child('name').val();
});
});
The event is triggered by another node and i want to retrive data from another node of firebase database. I have tried the above code but it produces an error saying TypeError: firebase.database.ref(...).once is not a function.

yes i got the answer we can use this code
exports.respublished = functions.database.ref('/Posts/{postid}').onWrite(event => {
const snapshot = event.data;
const postid = event.params.examid;
const uid = snapshot.child('uid').val();
const ispublic = snapshot.child('Public').val();
return admin.database().ref('Users/' + uid).once(event => {
const snapshot = event.data;
const name = snapshot.child('name').val();
});
});

Related

API host's rate-limit header not read properly

Here is my code (not the entire code, but I think this is the only really relevant part):
const timer = ms => new Promise(resolve => setTimeout(resolve, ms));
const createThrottler = (limitHeader) => {
let requestTimestamp = 0;
let rateLimit = 0;
return (requestHandler) => {
return async (...params) => {
const currentTimestamp = Number(Date.now());
if (currentTimestamp < requestTimestamp + rateLimit) {
const timeOut = rateLimit - (currentTimestamp - requestTimestamp);
requestTimestamp = Number(Date.now()) + timeOut;
await timer(timeOut)
}
requestTimestamp = Number(Date.now());
const response = await requestHandler(...params);
if (!rateLimit > 0) {
rateLimit = Math.floor((60 / response.headers.get(limitHeader)) * 1000);
}
console.log(limitHeader);
console.log(rateLimit);
return response;
}
}
}
const throttle = createThrottler("X-***-Ratelimit");
const throttleFetch = throttle(fetch);
function getRelease(idFiltered) {
return throttleFetch(`https://api.***.com/releases/${idFiltered}`, {
headers: {
'User-Agent': '***/0.1',
},
}).then(response => response.json())
.then(data => {
if (data.message === 'Release not found.') {
return { error: `Release with ID ${idFiltered} does not exist` };
} else {
const id = data.id;
const delimiter = document.getElementById("delimiter").value || "|";
const artists = data.artists ? data.artists.map(artist => artist.name) : [];
const barcode = data.identifiers.filter(id => id.type === 'Barcode')
.map(barcode => barcode.value);
var formattedBarcode = barcode.join(delimiter);
const country = data.country || 'Unknown';
const genres = data.genres || [];
const formattedGenres = genres.join(delimiter);
const labels = data.labels ? data.labels.map(label => label.name) : [];
const formattedLabels = labels.join(delimiter);
const catno = data.labels ? data.labels.map(catno => catno.catno) : [];
const formattedCatNo = catno.join(delimiter);
const styles = data.styles || [];
const formattedStyles = styles.join(delimiter);
const tracklist = data.tracklist ? data.tracklist
.map(track => track.title) : [];
const formattedTracklist = tracklist.join(delimiter);
const year = data.year || 'Unknown';
const format = data.formats ? data.formats.map(format => format.name) : [];
const qty = data.formats ? data.formats.map(format => format.qty) : [];
const descriptions = data.formats ? data.formats
.map(descriptions => descriptions.descriptions) : [];
const preformattedDescriptions = descriptions.toString()
.replace('"', '""').replace(/,/g, ', ');
const formattedDescriptions = '"' + preformattedDescriptions + '"';
console.log(idFiltered,
artists,
format,
qty,
formattedDescriptions,
formattedLabels,
formattedCatNo,
country,
year,
formattedGenres,
formattedStyles,
formattedBarcode,
formattedTracklist
)
return [idFiltered,
artists,
format,
qty,
formattedDescriptions,
formattedLabels,
formattedCatNo,
country,
year,
formattedGenres,
formattedStyles,
formattedBarcode,
formattedTracklist
];
}
});
}
But the "X-***-Ratelimit" header is clearly not being read correctly, as when I do
console.log(limitHeader);
console.log(rateLimit);
I initially get back
object
and thereafter
X-***-Ratelimit
Infinity
From the host's documentation:
We attach the following headers to responses to help you track your rate limit use:
X-***-Ratelimit: The total number of requests you can make in a one minute window.
X-***-Ratelimit-Used : The number of requests you’ve made in your existing rate limit window.
X-***-Ratelimit-Remaining: The number of remaining requests you are able to make in the existing rate limit window.
Any help please? TIA.
Edit: amazingly, I managed to greatly increase the rate-limit by getting my app authenticated thusly:
headers: {
'User-Agent': '***/0.1',
'Authorization': '*** key=***, secret=***',
},
However, I just took the key and secret from the site documentation, and I now get back this JSON response:
message - "Invalid consumer key/secret. Please register an app before making requests."
Edit2: OK, I worked out how to register my app now. I'm proceeding to further tests.
Edit3: the rate-limit in effect from the host is much better now, but my app is still not reading the header from the response correctly, so limitHeader is still coming back as "Infinity", instead of some meaningful/appropriate value.

Getting Data from Firestore for web

I currently try to use firebase for web and get data from Firestore.
This is my code for bring the all my data from Firestore.
function FireStoreGetAllData() {
let db = firebase.firestore();
let dataMap = new Map();
db.collection("User").get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(doc.id, " => ", doc.data());
let dataset = new Map();
let docId = doc.id;
let docdata = doc.data();
let firstName = docdata.first;
let lastName = docdata.last;
let bornData = docdata.born;
dataset.set('first', firstName);
dataset.set('last', lastName);
dataset.set('born', bornData)
dataMap.set(docId, dataset);
});
});
console.log('dataSet',dataMap.entries());
return dataMap;}
Problem is the "dataMap" always return null every time.
I debug this issue and find out that "db.colloction" is execute the code after "return dataMap".
What am I missing?
db.collection is execute after return dataMap because of the asynchronous.
Make you FireStoreGetAllData as async function then you will get your dataMap.
async function FireStoreGetAllData() {
let db = firebase.firestore();
let dataMap = new Map();
const querySnapshot = await db.collection("User").get();
querySnapshot.forEach((doc) => {
let dataset = new Map();
let docId = doc.id;
let docdata = doc.data();
let firstName = docdata.first;
let lastName = docdata.last;
let bornData = docdata.born;
dataset.set('first', firstName);
dataset.set('last', lastName);
dataset.set('born', bornData)
dataMap.set(docId, dataset);
});
return dataMap;
}

Variables are unable to be found by required code even if they're defined already

When I require code and load it into my main code for my Discord bot, it's unable to find variables or sub parts of them even if they're defined in the main code.
Required code:
module.exports.stupid = () => {
bot.on('messageCreate', (msg) => {
if (msg.content === 'yes'){
bot.createMessage(msg.channel.id,'yes!!')
}
});
}
-- Code in main script
const Eris = require('eris');
const axios = require('axios');
const firebase = require('firebase/app');
const FieldValue = require('firebase-admin').firestore.FieldValue
const admin = require('firebase-admin');
const serviceAccount = require('./serviceAccount.json');
// Commands
const cm1 = require('./staff.js')
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
})
let db = admin.firestore()
const bot = new Eris('token_removed');
let prefix = ';'
const sprefix = ">"
const botname = "bee"
const version = '0.6.6'
const emoji = '<:bee_logo:730125457638425039>'
const semoji = '<:bshield:729463155587022860>'
const remoji = 'buzz:683498511341191245'
const bee_check = '<:bee_check:729878268811018300>'
const bee_dash = '<:bee_dash:729878268790177862>'
const bee_x = '<:bee_x:729878268848898159>'
const hex = 0xF3DC3E
const gethex = 'F3DC3E'
const server = "Amazon (Linux/UNIX)"
const today = new Date();
const time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
cm1.stupid()
You'll have to edit a few lines in order to make everything work as intended :
Replace your module.exports.stupid = () => { with module.exports.stupid = (client) => {
When calling the function (cm1.stupid()), you need to pass the bot variable as an argument like so: cm1.stupid(client)
Hope this helps !

Uncaught (in promise) TypeError: Failed to fetch

** I have a problem when I try to get data back from database.
How to fix this bug, please ? **
const currentEl_one = document.getElementById('currency-one');
const amountEl_one = document.getElementById('amount-one');
const currentEl_two = document.getElementById('currency-two');
const amountEl_two = document.getElementById('amount-two');
const rateEl = document.getElementById('rate');
// Fetch exchange rates and update the DOM
const calculate() => {
const currency_one = currentEl_one.value;
const currency_two = currentEl_two.value;
fetch(`https://api.exchangerate-api.com/v6/latest/${currency_one}`)
.then(res => res.json())
.then(data => {
const rate = data.rates[currency_two];
rateEl.innerHTML = `1 ${currency_one} = ${rate} ${currency_two}`;
amountEl_two.value = (amountEl_one.value * rate).toFixed(2);
});
}
// Event Listener
currentEl_one.addEventListener('change', calculate);
amountEl_one.addEventListener('input', calculate);
currentEl_two.addEventListener('change', calculate);
amountEl_two.addEventListener('input', calculate);
swap.addEventListener('click', () => {
const temp = currentEl_one.value;
currentEl_one.value = currentEl_two.value;
currentEl_two.value = temp;
calculate();
})
calculate();

Refactoring async functions in javascript

I have written a program to extract links to download photos in three steps:
The getPersons() function get the complete list of people to traverse.
Get the photos download links from the list of persons.
Download from the list created in step 2.
I am trying to refactor step 2 into an async function.
Is there an easy way to refactor second step into a function to make the code more readable?
Ideally, I would like to retrieve all the links and only then, start the download.
const axios = require("axios");
const cheerio = require("cheerio");
const url = "https://www.website.com";
const persons = [];
async function getPersons() {
await axios.get(url).then(response => {
const html = response.data;
const $ = cheerio.load(html);
const personList = $(".bio-btn");
console.log(personList.length);
personList.each(function() {
const link_raw = $(this).attr("href");
const link = url + link_raw;
const name = link_raw.replace("/bio/", "");
person.push({
name,
link
});
});
});
}
getPersons().then(function() {
persons.forEach(async function(person) {
var personLink = person.link;
await axios.get(personLink).then(response => {
const html = response.data;
const $ = cheerio.load(html);
const snapshots = $(".ratio-4-3");
snapshots.each(function() {
const pic = $(this).attr("style");
if (pic != undefined && pic.includes("biopicture")) {
var bioPhoto = s[1];
}
});
});
});
});
You are hardly getting much benefit out of your asynchronicity, as you end up making serial requests. I'd write it this way (untested):
async function getPersons() {
const response = await axios.get(url);
const html = response.data;
const $ = cheerio.load(html);
const personList = $('.bio-btn');
const persons = [];
personList.each(function() {
const link_raw = $(this).attr('href');
const link = url + link_raw;
const name = link_raw.replace("/bio/", "");
persons.push({
name,
link,
});
});
return persons;
};
async function getSnapshots() {
const persons = await getPersons();
const linkPromises = persons.map(person => axios.get(person.link));
const linkResponses = await Promise.all(linkPromises);
linkResults.forEach(response => {
const html = response.data;
const $ = cheerio.load(html);
const snapshots = $(".ratio-4-3");
// ...
});
}
I would refactor it like this. Removing .then() methods and the function keyword on anonymous functions makes the code look cleaner.
Using Promise.all() enables you to start all the downloads asynchronously which could be better than downloading images one by one.
const axios = require('axios');
const cheerio = require('cheerio');
const url = 'https://www.website.com';
async function getPersons() {
const response = await axios.get(url);
return extractPersonList(response);
}
// Step 1
function extractPersonList(response) {
const persons = [];
const html = response.data;
const $ = cheerio.load(html);
const personList = $('.bio-btn');
console.log(personList.length);
personList.each(() => {
const link_raw = $(this).attr('href');
const link = url + link_raw;
const name = link_raw.replace('/bio/', '');
persons.push({
name,
link
});
});
return persons;
}
async function getPhotos() {
const persons = await getPersons();
const promisies = persons.map(p => axios.get(p.link));
// Step 2
const responses = await Promise.all(promisies);
// Step 3
responses.forEach(response => {
const html = response.data;
const $ = cheerio.load(html);
const snapshots = $('.ratio-4-3');
snapshots.each(() => {
const pic = $(this).attr('style');
if (pic && pic.includes('biopicture')) {
var bioPhoto = s[1];
}
});
});
}
// Call getPhotos to start the process
getPhotos();

Categories