I am successfully retrieving data from my Firebase Realtime Database, but I am having trouble storing it and rendering it to my web page with React. Can anyone tell me what is currently wrong with my process? And/or can you share an example of 'proper' storing/rendering process in a similar use case?
Here is how I am rendering stored data:
function Dashboard() {
var player_data;
var name_string;
return (
<div className="dashboard">
<h2>{player_data && player_data.settlement.settlement_name}</h2> {/* NOT RENDERING */}
</div>
);
And here is the function that is getting player_data that is working, which is successfully writing the data to the console:
function GetPlayerData(){
Firebase.database().ref().child("players").child(currentUser.uid).get().then((snapshot) => {
if (snapshot.exists()) {
console.log(snapshot.val());
player_data = snapshot.val();
console.log(player_data.settlement.settlement_name)
console.log(player_data.player_data.ancestor_name)
name_string = JSON.stringify(player_data.settlement.settlement_name)
} else {
console.log("No data available");
}
}).catch((error) => {
console.error(error);
});
}
Many thanks!
NEXT ATTEMPT: I have attempted to store the player_data with useState as a const JSON variable as follows, and as a result am receiving "TypeError: Cannot read properties of undefined (reading 'settlement_name')"
function Dashboard() {
const [ player_data, setPlayerData ] = useState();
return (
<div className="dashboard">
<h2>{player_data && player_data.settlement.settlement_name}</h2> {/* NOT RENDERING */}
<h2>{player_data && player_data.player_data.ancestor_name}</h2> {/* NOT RENDERING */}
</div>
And here is my updated GetPlayerData():
Firebase.database().ref().child("players").child(currentUser.uid).get().then((snapshot) => {
if (snapshot.exists()) {
console.log(snapshot.val());
setPlayerData(snapshot.val());
console.log(player_data.settlement.settlement_name)
console.log(player_data.player_data.ancestor_name)
} else {
console.log("No data available");
}
}).catch((error) => {
console.error(error);
});
}
);
Here is a screenshot of how my database is currently structured:
Any suggestions warmly appreciated. Thanks for reading! :)
WORKING CODE!:
function Dashboard() {
const [ playerData, setPlayerData ] = useState();
return (
<div className="dashboard">
<h2>{playerData && playerData.settlement.settlement_name}</h2> {/* RENDERING!! */}
<h2>{playerData && playerData.player_data.ancestor_name}</h2> {/* RENDERING! */}
</div>
And here is my updated GetPlayerData():
Firebase.database().ref().child("players").child(currentUser.uid).get().then((snapshot) => {
if (snapshot.exists()) {
console.log(snapshot.val());
setPlayerData(snapshot.val());
console.log(playerData) {/* NOT LOGGING : RETURNING UNDEFINED */}
console.log(playerData.settlement.settlement_name) {/* NOT LOGGING : RETURNING TypeError: Cannot read properties of undefined (reading 'settlement') */}
} else {
console.log("No data available");
}
}).catch((error) => {
console.error(error);
});
}
);
CodePudding user response:
You'll need to store the player data in the state of your component (by calling setState
or a useState
hook) when you get it from Firebase, so that it triggers a re-render. Your rendering code then can read the data from the state.
See for a pretty short example my answer here: Initiate React components with data from Firebase database? or a slightly longer one here: Retrieving items from firebase and dynamiccaly populating it in react native
CodePudding user response:
You can use firebase API to get the data from the firebase Real-Time database and store it in a state or redux store. Use useEffect to call the async function.
const getData=async ()=>{
const response=await fetch('firebase API url');
const data=await response.json();
setPlayerData(data)
}
useEffect(()=>{
getData()
},[]);
For rendering data into JSX, let me know which type of data you are retrieving from firebase. Are you returning Object or Array of Objects?
Based on the return value we should write our code in JSX.
If you are returning an object:
const playerdata={name:'Roomba',settlement:{settlement_name:'RumCity'}}
JSX Code:
<div>
<h1>{playerData.name} {playerData.settlement.settlement_name}</h1>
If your response from firebase is an array of objects then you need to use the map function to render all the objects in UI.
Hope this helpful, happy coding. Let me know if you have any doubts :)