Circumstances: For my app project that uses a realtime database I'm trying to load in data from all machines that are associated with the user. The machines that the user should see are dependent on the related company (cid) and which machines belong to that company.
Problem: I have used the Firebase v9 docs as much as possible and have created the code you can see below. However, this code only returns the correct machines after 3 re-renders. It looks like every onValue
command only returns something after a re-render. Can someone explain to me a way in which I can get the full data without forcefully re-rendering the screen? I have already tried to use the get
command asynchronously but this didn't seem to change anything.
useEffect(() => {
const auth = getAuth();
const db = getDatabase();
const userRef = ref(db, "users/" auth.currentUser.uid "/cid");
onValue(userRef, (snapshot) => {
const cid = snapshot.val();
setCid(cid, true);
});
const machinesRef = ref(db, "companies/" cid "/machines");
onValue(machinesRef, (snapshot) => {
const fetchedData = [];
snapshot.forEach((childSnapshot) => {
const childKey = childSnapshot.key;
const childData = childSnapshot.val();
const parsRef = ref(db, "machines/" childKey);
onValue(parsRef, (snapshot) => {
const parData = snapshot.val();
fetchedData.push(
new Machine(
childKey,
cid,
childData.type,
childData.creation,
parData.temperature
)
);
});
});
setData(fetchedData);
});
console.log(cid); # Outputted in the results section
console.log(data); # Outputted in the results section
}, []);
Results:
Render 1:
null
Array []
Render 2:
cid # This is correct
Array []
Render 3:
cid
Array [
Machine {
"companyId": "cid",
"creation": "creation",
"id": "23rff3345GRR",
"temperature": 99,
"type": "type",
},
Machine {
"companyId": "cid",
"creation": "creation",
"id": "3454egGR3",
"temperature": 2,
"type": "type",
},
]
CodePudding user response:
You'll need to move the call to setData
into the onValue
handler:
onValue(machinesRef, (snapshot) => {
const fetchedData = [];
snapshot.forEach((childSnapshot) => {
const childKey = childSnapshot.key;
const childData = childSnapshot.val();
const parsRef = ref(db, "machines/" childKey);
onValue(parsRef, (snapshot) => {
const parData = snapshot.val();
fetchedData.push(
new Machine(
childKey,
cid,
childData.type,
childData.creation,
parData.temperature
)
);
setData(fetchedData); //