ïm trying to send a notifications to all the users that a device have in firebase database, but it says: "ReferenceError: value is not defined" in the register of the cloud function.
What is supposed to do is: every time a change is made in "Notifications", you must obtain the data that was changed, with this data look in the device table and send a notification to all the tokens that are in that device.
This is the error:
Code of the cloudfunction:
const functions = require('firebase-functions');
const admin = require('firebase-admin'); // this is the Admin SDK, not firebase-functions
admin.initializeApp(functions.config().firebase);
const db = admin.database()
const ms = admin.messaging()
exports.notifications = functions.database.ref('Notifications/{id}').onUpdate(async(evt) =>{
const payload = {
notification:{
title : 'Alarma se activó tu cerca',
body : 'Se activó tu cerca, revisala',
badge : '1',
sound :'defaul'
}
};
//Get Notification Device ID
const notySnap = await db.ref('Notification/').once('value');
var devicee = notySnap.notty;
var dev = JSON.stringify(devicee);
//Get number of users that the device had
const usersSnap = await db.ref('Devices/'+ dev + '/Users').once(value)
const nUsers = usersSnap.nUsers;
var Nusers = JSON.stringify(nUsers);
var nNUsers = parseInt(Nusers);
//Send notification to the number of users that exist
if (Nusers !== null){
for(i = 1; 1 <=nNUsers; i++){
if(i === 1){
const userToSendP1 = usersSnap.user1;
var userToSend1 = JSON.stringify(userToSendP1);
Console.log("Mensaje enviado a user 1");
return ms.sendToDevice(userToSend1, payload);
}else if(i === 2){
const userToSendP2 = usersSnap.user2;
var userToSend2 = JSON.stringify(userToSendP2);
Console.log("Mensaje enviado a user 2");
return ms.sendToDevice(userToSend2, payload);
}else if(i === 2){
const userToSendP3 = usersSnap.user3;
var userToSend3 = JSON.stringify(userToSendP3);
Console.log("Mensaje enviado a user 3");
return ms.sendToDevice(userToSend3, payload);
}else if(i === 2){
const userToSendP4 = usersSnap.user4;
var userToSend4 = JSON.stringify(userToSendP4);
Console.log("Mensaje enviado a user 4");
return ms.sendToDevice(userToSend4, payload);
}
}
}
return null
})
DataBase:
In this line:
const usersSnap = await db.ref('Devices/'+ dev + '/Users').once(value)
value is a variable that you never defined. That's what the error message means. You probably meant this instead, with 'value' as a string:
const usersSnap = await db.ref('Devices/'+ dev + '/Users').once('value')
Related
I have a discord bot taking every message on a specific channel (you can type only once on it).
For each message, I put the message on a spreadsheet.
To minimize google API calls on my spreadsheet, I've implemented this :
I'm checking how many users wrote per minute.
If 10 or less : I'm calling my updatesheet function = working perfectly.
If 11 or more : I'm delaying the call with a setInterval (I took care to delay not more than 10per minute in the future aswell) = not working
I get this error message :
message: 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential.
which I do not understand since I'm using the exact same updatesheet function :
async function update(placeId,authorId,adressId,pointsNumber,tokensWon) {
await doc.useServiceAccountAuth({
client_email: creds.client_email,
private_key: creds.private_key,
});
await doc.loadInfo(); // loads document properties and worksheets
let sheetdailyPoints = doc.sheetsByIndex[1];
var date = new Date();
const year = date.getFullYear()
const month = `${date.getMonth() + 1}`.padStart(2, "0")
const day = `${date.getDate()}`.padStart(2, "0")
const stringDate = [day, month, year].join("/")
const rowPointsAdded = await sheetdailyPoints.addRow({
Date: stringDate,
AuthorId: authorId,
Place: placeId,
Adress: adressId,
Points: pointsNumber
});
let sheetTokensXP = doc.sheetsByIndex[3];
const rows2 = await sheetTokensXP.getRows();
var addedTokensXP = false;
let = length = rows2.length;
for(let i = 0; i < length; i++){
if(rows2[i].Adress == adressId) {
if(rows2[i].Points!='')
rows2[i].Points = parseInt(rows2[i].Points)+parseInt(pointsNumber);
else
rows2[i].Points = parseInt(pointsNumber);
rows2[i].XP = parseInt(rows2[i].XP)+200;
rows2[i].Tokens = parseInt(rows2[i].Tokens)+parseInt(tokensWon);
await rows2[i].save();
addedTokensXP=true;
return rows2[i].Tokens;
}
}
if (addedTokensXP == false) {
const rowAdded3 = await sheetTokensXP.addRow({
Adress: adressId,
Points: pointsNumber,
Tokens: tokensWon,
XP: 200
});
await rowAdded3.save();
return tokensWon;
}
}
The main function:
const prevMap = new Map();
for (i=0; i<61; i++) {
prevMap.set(i,0);
}
async function updateSheets(message,currentMin,ladderNumber,placeId,authorId,adressId,pointsNumber,tokensWon) {
if(currentMin === prevMin) {
nbUpdateAtMin = prevMap.get(currentMin);
nbUpdateAtMin++;
if(nbUpdateAtMin>10) {
let nbMinAdded = 0;
let foundPlaceAtMin;
let foundPlace = false;
for (i=currentMin+1; foundPlace; i++) {
if (prevMap.get(i) < 11 ) {
foundPlaceAtMin = i;
foundPlace = true;
}
}
nbMinAdded = foundPlaceAtMin-currentMin;
setInterval(function() {riddle.update(placeId,authorId,adressId,pointsNumber,tokensWon)},nbMinAdded*60000);
let value = prevMap.get(currentMin+nbMinAdded);
prevMap.set(currentMin+nbMinAdded,value+1);
}
else {
let value = prevMap.get(currentMin);
prevMap.set(currentMin,value+1);
riddle.update(placeId,authorId,adressId,pointsNumber,tokensWon);
}
}
else {
prevMap.set(prevMin,0);
let value = prevMap.get(currentMin);
prevMap.set(currentMin,value+1);
prevMin = currentMin;
riddle.update(placeId,authorId,adressId,pointsNumber,tokensWon)
}
}
So I have a app where I loades messages from my Server/Database. Now I have a big problem which is not really great for the users:
--> When I for loop the messages payload from the backend my whole App is hanging and I can't click anywhere else to e.g. go back and so on.
This is my for loop:
const handleMessagesPayload = (messages, new_page_number) => {
if (messages != null && messages != "undefined" && messages != "None"){
setPageNumber(new_page_number)
console.log(messages)
for (var i = 0; i < messages.length; i++) {
appendChatMessage(messages[i], false)
};
}
}
appendChatMessage function:
const appendChatMessage = (data, isNewMessage) => {
var msg = data.message
var timestamp = data.natural_timestamp
var user_id = data.user_id
var username = data.username
var message_id = data.message_id
logData(msg, timestamp, user_id, username, isNewMessage, message_id)
}
//add the new Messages to array
const logData = (msg, timestamp, user_id, message_username, isNewMessage, message_id) => {
const newMessage = {"message": msg, "username": message_username, "timestamp": timestamp, "message_id": message_id}
newChatMessage.push(newMessage) //newChatMessage is the array I was talking about
};
Do you have any useStates()? This might be the problem if you have any of them because they are very slow.
I am working on a node script where I will be opening and closing the browser using child process but its opening the browser but not able to close it on pressing Ctrl + C.
Here's my code:
const { kill } = require('process');
var start = (process.platform == 'darwin'? 'open': process.platform == 'win32'? 'start': 'xdg-open');
//open browser
var url = 'https://www.google.com';
var cmd = start + ' ' + url;
var child = require('child_process').exec(cmd, function(error, stdout, stderr) {
if (error) {
console.log('exec error: ' + error);
}
});
process.on('SIGINT', function() {
kill(child.pid, 'SIGINT');
fs.writeFile(./scraper.js)
process.exit();
});
scarper.js
const cheerio = require('cheerio');
const request = require('request-promise');
const fs = require('fs');
const link="https://www.imdb.com/chart/top/?ref_=nv_mv_250";
(async()=>{
const html = await request(link);
const $ = cheerio.load(html);
const table = $('.lister-list');
const rows = table.find('tr');
const data = [];
for(let i=0;i<rows.length;i++){
const row = rows.eq(i);
const cols = row.find('td');
const rank = i+1;
const title = cols.eq(1).find('a').text().trim();
const year = cols.eq(1).find('span').text().trim();
const rating = cols.eq(2).text().trim();
const votes = cols.eq(4).text();
const image = cols.eq(1).find('img').attr('src');
const movie = {
rank: rank,
title: title,
year: year,
rating: rating,
votes: votes,
image: image
};
data.push(movie);
}
console.log(data);
fs.writeFile('./data.json',JSON.stringify(data));
})();
I am working on a node.js app where I am using socket.io to send data to multiple clients but the socket is only able to send data to one client i.e if I open my webpage in two tabs its not working in both the tabs but when I open just 1 tab of webpage it is able to transmit the data.I dont know why? Can someone help,Here's my code:
try to use
setTimeout((function() {
return process.abort();
}), 5000);
or try
setTimeout((function() {
return process.kill(process.pid);
}), 5000);
I hope to seek help from someone if possible. In the following code. Im trying to console.log() data from My Firebase reference as you can see in my code below. But the Console.log() is returning null instead of the values that are there in Firebase Realtime Database. I have also provided the code for adding which is working well. Please have a look the image of my database if it helps. I am not getting any other error in my console except the fact that this is returning null.
function addFamilyMember() {
var NameOfMember = document.getElementById("newFamilyMemberName").value;
var DoBOfMember = document.getElementById("newFamilyMemberDoB").value;
var EmailOfMember = document.getElementById("newFamilyMemberEmail").value;
var ContactOfMember = document.getElementById("newFamilyMemberContactNo").value;
if (
NameOfMember.length == "" ||
DoBOfMember.length == "" ||
EmailOfMember.length == "" ||
ContactOfMember.length == ""
) {
alert("Please enter all details of your Family Member");
} else {
var user = firebase.auth().currentUser;
var uid;
if (user != null) {
uid = user.uid;
}
firebase
.database()
.ref("/Users/" + uid + "/Family/" + NameOfMember)
.set({
MemberName: NameOfMember,
MemberDOB: DoBOfMember,
MemberEmail: EmailOfMember,
MemberContact: ContactOfMember,
});
}
}
var user = firebase.auth().currentUser;
var uid;
if (user != null) {
uid = user.uid;
}
firebase
.database()
.ref("/Users/" + uid + "/Family/")
.on("value", function (snap) {
var mName = snap.child("MemberName").val();
var mDOB = snap.child("MemberDOB").val();
var mEmail = snap.child("MemberEmail").val();
var mContact = snap.child("MemberContact").val();
console.log(mName + " " + mEmail + " " + mContact + " " + mDOB);
});
The problem is you are fetching the whole Family node and trying to access data of each member.
I tried to recreate your database structure and got this in console on running the code.
{
"Name One": {"MemberContact":10000,"MemberName":"Name Two"},
"Name Two": {"MemberContact":10002,"MemberName":"Name Two"}
}
so if you want to get data of each user from that then try using forEach this way.
Object.keys(snap.val()).forEach(key => {
const memberData = snap.val()[key]
//Data of each member
var mName = memberData["MemberName"]
var mDOB = memberData["MemberDOB"]
var mEmail = memberData["MemberEmail"]
var mContact = memberData["MemberContact"]
console.log(mName + " " + mEmail + " " + mContact + " " + mDOB);
})
When loading the page for the first time, firebase.auth().currentUser shouldn't be used because Firebase Auth needs to check if the user's login session is valid first.
let currentUserFamilyRef = null;
// for use with .on("value") and .off("value")
function onValueFamilyListener(snapshot) {
const familyMembers = [];
snapshot.forEach((familyMemberSnapshot) => {
const MemberName = snap.child("MemberName").val();
const MemberDOB = snap.child("MemberDOB").val();
const MemberEmail = snap.child("MemberEmail").val();
const MemberContact = snap.child("MemberContact").val();
familyMembers.push({ MemberName, MemberDOB, MemberEmail, MemberContact });
console.log(MemberName + " " + MemberDOB + " " + MemberEmail + " " + MemberContact);
}
// TODO: do something with the array of family members familyMembers
}
// for showing loading state
function showLoadingIcon(visible) {
if (visible) {
// TODO: show the icon
// TODO: disable the submit button
} else {
// TODO: hide the icon
// TODO: enable the submit button
}
}
// for when addFamilyMember() is called while signed out
function addFamilyMemberSignedOut() {
alert('You need to sign in first!');
return false;
}
// for when addFamilyMember() is called while signed in
function addFamilyMemberSignedIn() {
const NameOfMember = document.getElementById("newFamilyMemberName").value;
const DoBOfMember = document.getElementById("newFamilyMemberDoB").value;
const EmailOfMember = document.getElementById("newFamilyMemberEmail").value;
const ContactOfMember = document.getElementById("newFamilyMemberContactNo").value;
if (
NameOfMember.length == "" ||
DoBOfMember.length == "" ||
EmailOfMember.length == "" ||
ContactOfMember.length == ""
) {
alert("Please enter all details of your Family Member");
return false;
}
const user = firebase.auth().currentUser;
if (user === null) {
// shouldn't get here, but just in case.
alert('You need to sign in first!');
return false;
}
const uid = user.uid;
showLoadingIcon(true);
firebase
.database()
.ref("/Users/" + uid + "/Family/" + encodeURIComponent(NameOfMember)) // escape names as they may contain symbols, etc.
.set({
MemberName: NameOfMember,
MemberDOB: DoBOfMember,
MemberEmail: EmailOfMember,
MemberContact: ContactOfMember,
})
.then(
() => {
// saved family member's data successfully
showLoadingIcon(false);
// reset form
document.getElementById("newFamilyMemberName").value = "";
document.getElementById("newFamilyMemberDoB").value = "";
document.getElementById("newFamilyMemberEmail").value = "";
document.getElementById("newFamilyMemberContactNo").value = "";
alert('Information saved!');
},
(err) => {
// failed to save family member's data
showLoadingIcon(false);
// err.code may lead to more specific error information
console.error(err);
alert('Failed to save information!');
}
);
}
// for calling the correct addFamilyMember version
let addFamilyMember = addFamilyMemberSignedOut;
showLoadingIcon(true); // while loading the user's info, show a loading icon
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// A user is (newly/already) signed in.
// create a reference for this user's family
const newUserFamilyRef = firebase.database()
.ref("/Users/" + user.uid + "/Family");
if (currentUserFamilyRef !== null) {
// if the old user and new user are the same, do nothing
// but if they've changed, remove the old listener and update currentUserFamilyRef
if (!currentUserFamilyRef.isEqual(newUserFamilyRef)) {
currentUserFamilyRef.off("value", onValueFamilyListener);
currentUserFamilyRef = newUserFamilyRef;
}
} else {
currentUserFamilyRef = newUserFamilyRef;
}
// use the "signed in" version of addFamilyMember
addFamilyMember = addFamilyMemberSignedIn;
// attach listener to "/users/{user.uid}/Family"
currentUserFamilyRef.on("value", onValueFamilyListener);
} else {
// no user is signed in.
// use the "not signed in" version of addFamilyMember
addFamilyMember = addFamilyMemberSignedOut;
// if a user was logged in, clean up it's listener to prevent errors
if (currentUserFamilyRef !== null) {
currentUserFamilyRef.off("value", onValueFamilyListener);
}
// no user, so set the reference to null
currentUserFamilyRef = null;
}
showLoadingIcon(false);
});
You can't directly use firebase.auth().currentUser. First you need to check the authentication state of the user. Then only you can ask for the current user. So to do this you need to wrap it using authentication state observer.You can read more about it on firebase documentation: [https://firebase.google.com/docs/auth/web/start][1]
function addFamilyMember() {
var NameOfMember = document.getElementById("newFamilyMemberName").value;
var DoBOfMember = document.getElementById("newFamilyMemberDoB").value;
var EmailOfMember = document.getElementById("newFamilyMemberEmail").value;
var ContactOfMember = document.getElementById("newFamilyMemberContactNo").value;
firebase.auth().onAuthStateChanged((user) => {
if (user) {
if (
NameOfMember.length == "" ||
DoBOfMember.length == "" ||
EmailOfMember.length == "" ||
ContactOfMember.length == ""
) {
alert("Please enter all details of your Family Member");
} else {
var user = firebase.auth().currentUser;
var uid;
if (user != null) {
uid = user.uid;
}
firebase
.database()
.ref("/Users/" + uid + "/Family/" + NameOfMember)
.set({
MemberName: NameOfMember,
MemberDOB: DoBOfMember,
MemberEmail: EmailOfMember,
MemberContact: ContactOfMember,
});
}
}
var user = firebase.auth().currentUser;
var uid;
if (user != null) {
uid = user.uid;
}
firebase
.database()
.ref("/Users/" + uid + "/Family/")
.on("value", function (snap) {
var mName = snap.child("MemberName").val();
var mDOB = snap.child("MemberDOB").val();
var mEmail = snap.child("MemberEmail").val();
var mContact = snap.child("MemberContact").val();
console.log(mName + " " + mEmail + " " + mContact + " " + mDOB);
})
})}
Am trying to use the chaining method but am not sure how to that yet. I have researched online and still haven't found any success any help will be appreciated.
// The URL root if user searches by city
const API_ROOT_CITY = "http://api.geonames.org/searchJSON?q=";
// Parameters for geonames
const API_ROOT_PARAMS = "&maxRows=1"
// API KEY for geonames
const API_KEY = &username=kamara.moses;
// WeatherBit URL
const API_ROOT_BIT = "https://api.weatherbit.io/v2.0/forecast/daily?"
// Parameters for weatherbit
const API_BIT_PARAMS = "&city="
// API KEY for weatherbit
const API_BIT_KEY = "&key=cda6df51d9a24b8c9d54b830f4eadb51"
// PixaBay URL
const API_ROOT_PIXA = "https://pixabay.com/api/?"
// API KEY for pixabay
const API_PIXA_KEY = "key=19853981-85155ca595da994be43f034e6"
// Parameters for pixabay
const API_PIXA_PARAMS = "&q="
// Type of image from pixabay
const API_PIXA_IMAGE = "&image_type=photo"
// Main function of the program
// Grabs the user"s input, then forms URL, calls API, POSTS and updates UI
function clickRespond() {
// Grab user"s input
const cityInput = document.getElementById("city");
// Read values of zip and city
const city = cityInput.value;
// Form URL based on zip or city search
// (zip takes precendence if both were entered)
let url;
let bitURL;
let pixaURL;
if (city) {
url = API_ROOT_CITY + city + API_ROOT_PARAMS + API_KEY;
bitURL = API_ROOT_BIT + API_BIT_PARAMS + city + API_BIT_KEY;
pixaURL = API_ROOT_PIXA + API_PIXA_KEY + API_PIXA_PARAMS + API_PIXA_IMAGE;
}
// Call the API
getGeo(url)
// Prepares data for POST, calls the POST
.then(function (response) { // CHANGE: call it response
console.log(response)
const errorMessage = document.getElementById("error");
if (response.status == "200") { // CHANGE: check the status
errorMessage.classList.add("hide");
const city = response.geoNames.geonames[0].name; // Change
postJournal("/add", { city }) ;
// Calls to update the site with latest entry
updateUI();
} else {
console.log("Bad data entered");
errorMessage.classList.remove("hide");
return;
}
})
getWeather(bitURL)
.then(function (response) {
console.log(response)
const errorMessage = document.getElementById("error");
if (response.status == "200") {
errorMessage.classList.add("hide");
const icon = response.weatherBit.data[0].weather.icon;
const description = response.weatherBit.data[0].weather.description
const newDate = dateTime();
const date = newDate;
const highTemp = response.weatherBit.data[0].high_temp;
const lowTemp = response.weatherBit.data[0].low_temp
postJournal("/add", { icon: icon, description: description, date: date, highTemp: highTemp, lowTemp: lowTemp });
// Calls to update the site with latest entry
updateUI();
} else {
console.log("Bad data entered");
errorMessage.classList.remove("hide");
return;
}
})
getPix(pixaURL)
.then(function (response) {
console.log(response)
const errorMessage = document.getElementById("error");
if (response.status == "200") {
errorMessage.classList.add("hide");
const image = response.pixaBay.hits[0].webformatURL;
postJournal("/add", { image: image });
// Calls to update the site with latest entry
updateUI();
} else {
console.log("Bad data entered");
errorMessage.classList.remove("hide");
return;
}
})
}