簡體   English   中英

反應 firestore 子集合

[英]react firestore sub collection

我怎樣才能得到客戶的汽車清單

clients:
w21rffa3:
name: Johny
phone: 123123
cars:
fn1jnr12:
brand: AUDi
model: a6
number: 24f1
dsdasgf122:
brand: AUDi
model: a3
number: 62s14

我的代碼

const ref = firestore().collection('clients');
const [clientsList, setClientsList] = useState([]);
useEffect(() => {
  return ref.onSnapshot(clientsSnapshot => {
    const clients = [];
    const cars = [];
    clientsSnapshot.forEach(client => {
      const carsRef = ref.doc(client.id).collection('cars').onSnapshot(carsSnapshot => {
        carsSnapshot.forEach(car => {
          if (car.data().brand.length > 0) {
            const {
              brand,
              model,
              number
            } = car.data();
            cars.push({
              id: car.id,
              brand,
              model,
              number,
            });
          }
        });
        //Good result`

        console.log('After forEach: ', cars);
      });
      //Bad result
      console.log('After snapshot: ', cars);
      const {
        name,
        phone
      } = client.data();
      clients.push({
        id: client.id,
        name,
        phone,
        cars: cars,
      });
    });
    setClientsList(clients);
  });
}, []);

客戶汽車清單

您面臨的錯誤是由於誤用/誤解了基於異步/回調的函數的工作方式。 正如我在評論中所說 - good resultbad result - 由於 onSnapshot 是asyncbad result腳本在good result之前執行,並且你將回調 function 傳遞給它,當數據從 firebase 可用時執行,所以有點“晚於”代碼的 rest。

現在談談可以做什么。 代碼有點棘手,我沒有真正測試它,所以如果有任何問題 - 請告訴我。

const [clientsList, setClientsList] = useState([]);

useEffect(() => {
  let carsUnsubscribeFns = [];
  const clientUnsubscribeFn = ref.onSnapshot((clientsSnapshot) => {
    // Reset everything and stop previously created listeners for Cars
    setClientsList([]);
    carsUnsubscribeFns.forEach((x) => x());
    carsUnsubscribeFns = [];

    clientsSnapshot.forEach((c) => {
      const { name, phone } = c.data();
      
      const client = { id: c.id, name, phone };
      // In case you dont want to use optional chaining, 
      // remove the const client = ... line above
      // and uncomment the line below
      // but optional chaining is prefered anyway
      // const client = { id: c.id, name, phone, cars: [] };
      
      const carsUnsubscribeFn = ref
        .doc(client.id)
        .collection("cars")
        .onSnapshot((carsSnapshot) => {
          // Mutate the Client object directly
          client.cars = carsSnapshot.docs
            .map((x) => ({ id: x.id, ...x.data() }))
            .filter((x) => x.brand?.length > 0);
          // mark ClientsList as updated to force a rerender
          // due to we mutated one of the entities inside
          setClientsList((curr) => [...curr]);
        });
      carsUnsubscribeFns.push(carsUnsubscribeFn);
      setClientsList((curr) => {
        curr.push(client);
        return [...curr];
      });
    });

    // clean-up function returned from hook to stop all the listeners
    return () => {
      [clientUnsubscribeFn, ...carsUnsubscribeFns].forEach((x) => x());
    };
  });
}, []);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM