Reputation: 119
I am currently building a small web app with Firebase and React, but I am having trouble fetching for specific items in the Firebase from the React client-side.
That being said, I'm used to javascript, where a simple fetch might look something like:
const url = 'www.example.com/api/'
const id = '123'
fetch(url + id) <---specific
.then(res => res.json())
.then(result => this.setState({results: result})
.catch(err => console.log(err))
However, I haven't been able to find any documentation on something that looks similar with firebase.
A more specific issue below:
class StoryItem extends Component {
constructor(props) {
super(props);
this.state = {
story: this.props.location.myCustomProps
};
}
componentDidMount() {
//this should do a fetch request based on the
//params id to get the specific item in the firebase
//right now it is being passed as prop which is unreliable because when page refresh state is reset
//user should be able to access content
//without having to go to previous page
console.log(this.state.story)
}
One way I've tried to get the specific object from the firebase is this:
componentDidMount(props) {
const ref = firebase.database().ref("items");
ref.on("value", snapshot => {
let storiesObj = snapshot.val();
storiesObj
.child(this.props.match.params.id)
.then(() => ref.once("value"))
.then(snapshot => snapshot.val())
.catch(error => ({
errorCode: error.code,
errorMessage: error.message
}));
});
}
Any help would be appreciated, also, if anyone knows of any good documentation on firebase, feel free to send me a link.
Thank you
Upvotes: 1
Views: 7015
Reputation: 3883
The trick is, you don't have to get the value of all items first, as you do.
You should locate the items
ref, then lookup a child that you want and get the value of that child with .on
or .once
.
Something like that, based on your example code:
componentDidMount() {
firebase.database().ref("items");
.child(this.props.match.params.id)
.once("value")
.then(snapshot => snapshot.val())
.catch(error => ({
errorCode: error.code,
errorMessage: error.message
}));
}
For better understanding, let's take a look at the original code and try to figure out why it errors out:
componentDidMount(props) {
// ⬇️ this ref points to ALL items
const ref = firebase.database().ref("items");
// ⬇️ here we're asking for the value stored under the above ref
ref.on("value", snapshot => {
let storiesObj = snapshot.val();
/* so firebase gives us what we ask for, storiesObj
* is probably a huge js object with all the items inside.
* And since it's just a regular js object,
* it does not have a `child` method on it, thus calling .child errors out.
*/
storiesObj
.child(this.props.match.params.id)
.then(() => ref.once("value"))
.then(snapshot => snapshot.val())
.catch(error => ({
errorCode: error.code,
errorMessage: error.message
}));
});
}
Upvotes: 5