I am trying to query a value from a document in collection, in fire base, particularly "currentKilos":
I am using the below function to query it:
showKiols = () => {
db.collection('users').doc(this.props.user.uid).collection('mainData').doc('currentKilos').get().then.subscribe(value=> {
this.updatedKilos = value;
alert(this.updatedKilos);
})
}
However, I am getting attached error:
Also, I tried below function as well, but it is not working:
db.collection('users').doc(this.props.user.uid).collection('mainData').doc('currentKilos').valueChanges().subscribe(value => {
this.updatedKilos = value.currentKilos;
alert(this.updatedKilos)
})
FYI, this is the function to add currentKilos to firebase, and it is working fine:
updateKilos = () => {
db.collection('users').doc(this.props.user.uid).collection('mainData').doc('currentKilos').set({ currentKilos: this.state.currentKilos })
alert('Data Updated')
}
Appreciate your support.
I'm not sure where you get get().then.subscribe() from, but at the very least that then should be then((value)=>{...}).
Try the following:
showKiols = () => {
db.collection('users')
.doc(this.props.user.uid)
.collection('mainData')
.doc('currentKilos')
.get()
.then(value => {
this.updatedKilos = value.data();
alert(this.updatedKilos);
})
}
Related
Everyone does a weather app for api practice so I decided to do something different I'm using Pokeapi to make a small app. I have to call a few different apis to make it work how I want which is being done like this
const api = "https://pokeapi.co/api/v2/pokemon";
const apiMoves = "https://pokeapi.co/api/v2/move";
const apiSpecies = "https://pokeapi.co/api/v2/pokemon-species"
const searchBox = document.querySelector(".search-box");
searchBox.addEventListener("keypress", setQuery);
function setQuery(e) {
if (e.keyCode == 13) {
getResults(searchBox.value);
searchBox.value = "";
}
}
function getResults(query) {
const pokemonData = fetch(`${api}/${query}`)
.then((data) => {
return data.json();
});
pokemonData.then(displayResults)
pokemonData.then(data => {
return fetch(`${apiMoves}/${data.moves[0].move.name}`)
.then(data => data.json())
.then(move => {
console.log(move)
})
})
pokemonData.then(data => {
return fetch(`${apiSpecies}/${query}`)
.then(data => data.json())
.then(species => {
console.log(species)
})
})
}
all 3 of the end points are being logged in the console so I can see them. However looking at api call 2 I'm passing info from the first api call to get more info and that logs fine. When I'm trying to display the info from that 2nd api call it just returns undefined but in the console I can see all the endpoints.
the display results looks something like this.
function displayResults(pokemon) {
let name = document.querySelector('h2')
name.innerText = pokemon.name <-- this works.
let dmg1 = document.querySelector('.dmg1')
dmg1.innerText = pokemon.power <-- this is returning undefined but in the console "power" shows a number.
}
I've tried to replace the pokemon.power with move.power but that gives an error saying "move" is not defined.
I'm thinking that I'm simply calling the 2nd and 3rd api wrong? I'm not sure and trying to search for this issue is a bit rough.
any help is appreciated!
const pokeApiPrefix = 'https://pokeapi.co/api/v2/';
const apiPokemon = `${pokeApiPrefix}pokemon`;
const apiMoves = `${pokeApiPrefix}move`;
const apiSpecies = `${pokeApiPrefix}pokemon-species`;
const searchBox = document.querySelector('.search-box');
searchBox.addEventListener('keypress', setQuery);
function setQuery(e) {
if (e.keyCode == 13) {
getResults(searchBox.value.toLowerCase());
searchBox.value = '';
}
}
getResults('Dragonite'.toLowerCase());
function getResults(pokemon) {
let dmg1 = document.querySelector('.dmg1');
dmg1.innerText = `Getting results. Please wait...`;
const pokemonData = fetch(`${apiPokemon}/${pokemon}`)
.then((data) => data.json())
.then((data) => {
console.log(`pokemon data:`, data);
displayPokemonName(data);
const moveName = data.moves[0].move.name;
return fetch(`${apiMoves}/${moveName}`);
})
.then((data) => {
return data.json();
})
.then((data) => {
displayMovePower(data);
console.log(`move data:`, data);
return fetch(`${apiSpecies}/${pokemon}`);
})
.then((data) => data.json())
.then((data) => {
console.log(`species data:`, data);
});
}
// function displayResults(pokemon) {
// let name = document.querySelector('h2');
// name.innerText = pokemon.name;
// let dmg1 = document.querySelector('.dmg1');
// // I couldn't find 'power' attribute on api results, used id instead
// // https://pokeapi.co/docs/v2#pokemon
// dmg1.innerText = `#${pokemon.id}`;
// }
function displayPokemonName(pokemon) {
let name = document.querySelector('h2');
name.innerText = `Pokemon name: ${pokemon.name}`;
}
function displayMovePower(move) {
let dmg1 = document.querySelector('.dmg1');
dmg1.innerText = `Move power: ${move.id}`;
}
<input type="text" class="search-box" />
<h2></h2>
<div class="dmg1"></div>
I've created a snippet, chaining multiple promises and logging every result on the console.
As stated, it seems you are trying to use an attribute 'power', which is not present in the first pokemon api call
Here this line is not working because you are trying to access the attribute which does not exist in the object.
let dmg1 = document.querySelector('.dmg1')
dmg1.innerText = pokemon.power <-- this is returning undefined but in the console "power" shows a number.
What might work for you is:
dmg1.innerText = pokemon.moves[0].move.name
I have the following json structure:
Within "all" node I have an attribute "drinkId" and I'm trying to move it outside that child node bringing it one level up.
I'm trying to read the value without any luck
const cocktailRef= firebase
.database()
.ref("Ratings");
cocktailRef.once("value", (snapshot) => {
snapshot.forEach((child) => {
const drinkIdPass = child.ref.child("all").child("drinkId").value();
child.ref.update({ drinkId: drinkIdPass });
})
})
I've tried different variants of ".value()", same problem
There isn't any value() method on a DataSnapshot. It's val() Try refactoring your code like this:
const cocktailRef= firebase.database().ref("Ratings");
cocktailRef.once("value").then(async (snapshot) => {
const updates = { }
snapshot.forEach((child) => {
const drinkIdPass = child.val().all.drinkId
updates[`${child.key}/drinkId`] = drinkIdPass
})
await cocktailRef.update(updates)
console.log("Data updated")
})
So I have this current code:
const mutualGuilds = bot.guilds.cache.filter((guild) => {
return guild.members.cache.has(message.author.id);
});
if (mutualGuilds.roles.cache.has("guildid")) {
if (mutualGuilds.users.cache.has(user.id)) {
let userInGuild = mutualGuilds.users.cache.find(user.id).roles.add("roleid");
}
}
And when I try the command it outputs: Cannot read property 'cache' of undefined
If someone could help that would be amazing since my bot is on release today.
If you use the .filter method to get the mutualGuilds, it will return a collection. You can only access the .roles property on a single guild, so you need to grab the .first() one for example, like this:
const mutualGuilds = bot.guilds.cache.filter((guild) => {
return guild.members.cache.has(message.author.id);
});
if (mutualGuilds.first().roles.cache.has("guildid")) {
// ...
Or you can use the .each() method to execute the provided function once for each mutual guild:
const mutualGuilds = bot.guilds.cache.filter((guild) => {
return guild.members.cache.has(message.author.id);
});
mutualGuilds.each((guild) => {
if (guild.roles.cache.has("guildid")) {
// ...
});
I am trying to write a function in Cloud Functions that triggers every time a user gets created and which then saves that user into a list of users and finally increments a user counter.
However I am not sure if I am using promises correctly.
exports.saveUser = functions.auth.user().onCreate(event => {
const userId = event.data.uid
const saveUserToListPromise = db.collection("users").doc(userId).set({
"userId" : userId
})
var userCounterRef = db.collection("users").doc("userCounter");
const transactionPromise = db.runTransaction(t => {
return t.get(userCounterRef)
.then(doc => {
// Add one user to the userCounter
var newUserCounter = doc.data().userCounter + 1;
t.update(userCounterRef, { userCounter: newUserCounter });
});
})
.then(result => {
console.log('Transaction success!');
})
.catch(err => {
console.log('Transaction failure:', err);
});
return Promise.all([saveUserToListPromise, transactionPromise])
})
I want to make sure that even if many users register at once that my userCounter is still correct and that the saveUser function won't be terminated before the transaction and the save to the list has happened.
So I tried this out and it works just fine however I don't know if this is the correct way of achieving the functionality that I want and I also don't know if this still works when there are actually many users triggering that function at once.
Hope you can help me.
Thanks in advance.
The correct way to perform multiple writes atomically in a transaction is to perform all the writes with the Transaction object (t here) inside the transaction block. This ensures at all of the writes succeed, or none.
exports.saveUser = functions.auth.user().onCreate(event => {
const userId = event.data.uid
return db.runTransaction(t => {
const userCounterRef = db.collection("users").doc("userCounter")
return t.get(userCounterRef).then(doc => {
// Add one user to the userCounter
t.update(userCounterRef, { userCounter: FirebaseFirestore.FieldValue.increment(1) })
// And update the user's own doc
const userDoc = db.collection("users").doc(userId)
t.set(userDoc, { "userId" : userId })
})
})
.then(result => {
console.info('Transaction success!')
})
.catch(err => {
console.error('Transaction failure:', err)
})
})
I am trying to set the state inside of a firebase snapshot function but I am getting an Cannot read property 'setState' of null error. I am not sure how to make it work.
This is my code:
componentDidMount = () => {
const dataGoalRef = dbRef.child('goals/'+this.state.uid);
dataGoalRef.child("mainGoal").on("value", function(mainGoalKeySnapshot) {
var favoriteMainGoal = mainGoalKeySnapshot.val();
console.log(favoriteMainGoal);
var queryRef = dataGoalRef.orderByKey().equalTo(favoriteMainGoal);
queryRef.on("value", snap => {
this.setState({
dataGoal: snap.val(),
});
});
});
}
How can I do so?
I've just figured it out. I wasn't binding the first method. So the solution is:
componentDidMount = () => {
const dataGoalRef = dbRef.child('goals/'+this.state.uid);
dataGoalRef.child("mainGoal").on("value", (mainGoalKeySnapshot) => {
var favoriteMainGoal = mainGoalKeySnapshot.val();
console.log(favoriteMainGoal);
var queryRef = dataGoalRef.orderByKey().equalTo(favoriteMainGoal);
queryRef.on("value", snap => {
this.setState({
dataGoal: snap.val(),
});
});
});
}
Try by using arrow function instead of normal function declaration for callback which you have passed in dataGoalRef.child("mainGoal").on("value", function(mainGoalKeySnapshot){})
updated code
dataGoalRef.child("mainGoal").on("value", (mainGoalKeySnapshot) => {
....
....
});