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")
})
Related
I'm building an app using react-native and react-native-firebase and i'm running into an issue while trying to implement a comment section.
My tree of data is currently like that :
collection(comments)/doc(currentUser.uid)/collection(userComments)/doc(commentCreatorID)
Within this doc commentCreatorID there is all the data i need. So basically the content, a timestamp...
For this part everything works perfectly but in order to havethe commentCreator's infos stick with his post, i need to grab them somewhere else.
The way i do that is taking the doc(commentCreatorID), as it is the uid of this user and ask firestore to give me the data from the document with this same id within my "users" collection.
Here is my code :
const [comments, setComments] = useState([])
const [commentsReady, setCommentsReady] = useState([])
useEffect(() => {
setComments([])
setLoading(true)
firestore()
.collection('comments')
.doc(auth().currentUser.uid)
.collection('userComments')
.get()
.then((snapshot) => {
let comments = snapshot.docs.map(doc => {
const data = doc.data()
const id = doc.id
return {id, ...data}
})
setComments(comments)
})
.then(() => {
comments.forEach(comment => {
firestore()
.collection("users")
.doc(comment.id)
.get()
.then((snapshot) => {
const data = snapshot.data()
setCommentsReady({comments, ...data})
})
})
})
console.log(commentsReady)
setLoading(false)
}, [handleScroll4])
This doesn't seem to works well as for now. My log throw an empty array right into my face..
I'm grabbing each comment correctly tho and even each user's data corresponding to their uids.
I can log them once ForEach have been done.
But for some reason i can't have them set to my state commentsReady.
Did i miss something ?
Thanks for your time
The setters that the useState function returns are async. Copying data from one state to another is also an antipattern. Try using effects.
const TT = () => {
const [comments, setComments] = useState([]);
const [userInfos, setUserInfos] = useState([]);
const commentsView = comments.map(comment => {
// Reactively merge each comment with the appropriate user info
});
useEffect(() => {
firestore()
.collection('comments')
.doc(auth().currentUser.uid)
.collection('userComments')
.get()
.then((snapshot) => {
let comments = snapshot.docs.map(doc => {
const data = doc.data()
const id = doc.id
return {id, ...data}
});
setComments(comments);
});
}, []);
useEffect(async () => {
// Maybe keep a cache of fetched user datas, but not sure how this is architected
const snapshots = await Promise.all(comments.map(comment => {
return firestore()
.collection("users")
.doc(comment.id)
.get();
}));
setUserInfos(snapshots.map(snap => snap.data()));
}, [comments]);
};
When removing an item from my RTDB, my intention is to clean up user's likes if the item they like got removed.
With my data structure like so:
I am attempting to remove the nodes like this:
const updates = {};
//WORKS
updates[`/strains/${title}/`] = null;
updates[`/strainsMin/${title}/`] = null;
firebase
.database()
.ref('reviews')
.orderByChild('s')
.equalTo(title)
.once('value', snapshot => {
console.log(snapshot.val())
snapshot.forEach(child => {
console.log(child.key)
//WORKS
updates[`/reviews/${child.key}`] = null;
});
})
.then(() => {
firebase
.database()
.ref('userLikedStrains')
.orderByChild(title)
.equalTo(title)
.once('value', snapshot => {
console.log(snapshot.val() + 'likeylikeyyy')
snapshot.forEach(child => {
console.log(child.key)
//DOESNT WORK
updates[`/userLikedStrains/${child.key}/${title}`] = null;
});
firebase
.database()
.ref()
.update(updates);
})
For some reason this doesn't work. Is it because I am targeting a key (which is still a child?..)
I appreciate any help with this!
Cheers.
The code you shared is not writing anything back to the database yet. For that you need to call update after the loop.
Something like:
let ref = firebase
.database()
.ref('userLikedStrains');
ref.orderByChild(title)
.equalTo(title)
.once('value', snapshot => {
console.log(snapshot.val())
snapshot.forEach(child => {
console.log(child.key)
updates[`/userLikedStrains/${child.key}/${title}`] = null;
});
ref.update(updates);
})
I'm using firebase in my react native project.I am saving items and then getting those items in my app. But now I want to edit and delete items based on the key generated by the firebase for each item you can see in the ss.
When I get the data from firebase I'm getting on the items but not the key for each item.So that's why I'm unable to edit or delete items
Kindly help me out on how to do this.
enter image description here
here is my code of add item in the firebase.
export const addMeasurement = params => {
return async dispatch => {
dispatch(measurementLoading());
try {
firebaseService
.database()
.ref('/Measurements')
.push(params)
.then(res => {
measurementAdded(res);
});
} catch (err) {
dispatch(measurementFailed(err));
}
};
};
Here is the code to get items from firebase which was stored early
export const getMeasurements = () => {
return async dispatch => {
dispatch(measurementLoading());
try {
const ref = firebaseService.database().ref('/Measurements');
ref.on('value', snapshot => {
const values = snapshot.val();
if (values !== null) {
const newFreshArr = Object.values(values);
dispatch(measurementSuccess(newFreshArr));
}
});
} catch (err) {
dispatch(measurementFailed(err));
}
};
};
You can get the path of a snapshot like so:
let path = snapshot.ref.path.toString();.
You can then make changes to your Firebase database using that path.
Here’s the documentation on that: https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#ref
I'm trying to build a very simple app for searching articles and using the localstorage to display more info about each article but when I set to save into the session storage for some reason is saving the initial or previous state, I assume because I need to set async for this but I just can't figure how
This is how I have it right now, findArticleQuery() is called on the handleSubmit
useEffect(
() =>{
findArticlesQuery();
} ,[]
)
const findArticlesQuery = (query) => { //search function
axios.get(`url`)
.then(res => {
[res.data].map((val) =>(
setState(val)
))
}).catch(error => {
console.log(error.response)
});
}
const handleSubmit = (e) => {
e.preventDefault();
findArticlesQuery(e.target.search.value)
sessionStorage.setItem('localData', JSON.stringify(state)) //<--here I get the value of the previous state
e.target.search.value = '';
}
I need to use the session storage because I will have a detailed article component page.
Thank you guys!
You can get search result from findArticlesQuery() like below.
...
const findArticlesQuery = (query) => { //search function
return axios.get(`url`)
.then(res => {
setState(res.data)
return res.data
})
}
const handleSubmit = (e) => {
e.preventDefault();
findArticlesQuery(e.target.search.value)
.then(val => sessionStorage.setItem('localData', JSON.stringify(val)))
e.target.search.value = '';
}
For saving state in the localStorage with React Hooks, something I've been using and that is extremely convenient is useLocalStorage.
Disclaimer : I am not the creator of this lib.
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);
})
}