I am building backend app, when the order is placed I get console log but the screen doesn't get updated and also the back button(react navigation), response after few seconds.
const GetdataUsers = async () => {
let grabbedData1 = [];
let customerList1 = [];
await firebase
.database()
.ref(`/serviceProvider/${user1.uid}/franchise/customers`)
.orderByKey()
.on("value", (snapshot) => {
customerList1.push(snapshot.val());
// setCustomerList(customerList1);
if (customerList1) {
Object.keys(customerList1).map(function (key) {
let y = customerList1[key];
Object.keys(y).map(function (key2) {
let x = y[key2]; // get all customer id
// From that id fetch all the orders they have
firebase
.database()
.ref(`/orders/${x}`)
.orderByKey()
.on("value", (snapshot, key) => {
grabbedData1.push(snapshot.val());
console.log("grabbedData1....",grabbedData1);
// Grab all orders from the customers and set it
setShowloading(false);
setOrders(grabbedData1);
});
})
});
}
});
};
useEffect(() => {
GetdataUsers();
}, []); // [orders] tried this way also
When placing orders in bracket as shown above back button freezes and doesn't get any update . Also tried returning the data from function and setorder inside useEffect but stuck in a loop.
CodePudding user response:
At first query I fetch all the customers Ids that they have which is "x" (
let x = y[key2];
) then another query for all orders that customer (x) have and then store it to orders (setOrders(grabbedData1);
) and to print on the app
Issues I see with the code:
- You care mutating arrays in the
getDataUsers
function. - You've a set of nested firebase subscriptions that necessarily depend on the just updated
customerList
. - You don't unsubscribe from any firebase snapshot subscriptions.
I think it would be better to split this into two separate actions, or effects, one to handle the user's uid
changing to set the current customerList
state, and a second to handle fetching/updating the orders state when the customerList
state updates.
Example:
Update the customer list when user changes.
useEffect(() => {
const unsubscribe = firebase
.database()
.ref(`/serviceProvider/${user1.uid}/franchise/customers`)
.orderByKey()
.on("value", (snapshot) => {
setCustomerList(snapshot.val());
});
return unsubscribe;
}, [user1.uid]);
Update the orders when customer list updates.
useEffect(() => {
const innerSubscriptions = [];
if (customerList) {
setOrders([]); // <-- clear orders for new customers list
Object.values(customerList).forEach((customer) => {
Object.values(customer).forEach((id) => {
const unsubscribe = firebase
.database()
.ref(`/orders/${id}`)
.orderByKey()
.on("value", (snapshot, key) => {
const order = snapshot.val();
// Grab all orders from the customers and merge
setOrders((orders) => [...orders, order]);
});
innerSubscriptions.push(unsubscribe);
});
});
}
return () => {
innerSubscriptions.forEach((unsubscribe) => unsubscribe());
};
}, [customerList]);
CodePudding user response:
You have made an async function but you haven't used the await keyword. Also you'll have to create a state for loader and conditionally render a loader component till you have fetched all the data.