【问题标题】:How can I instantly load all my firebase entries without re-rendering?如何在不重新渲染的情况下立即加载所有 Firebase 条目?
【发布时间】:2021-12-29 22:51:14
【问题描述】:

情况:对于使用实时数据库的应用程序项目,我正在尝试从与用户关联的所有机器中加载数据。用户应该看到的机器取决于相关公司 (cid) 以及哪些机器属于该公司。

问题:我已尽可能多地使用Firebase v9 docs,并创建了您可以在下面看到的代码。但是,此代码仅在 3 次重新渲染后返回正确的机器。看起来每个onValue 命令只在重新渲染后返回一些东西。有人可以向我解释一种无需强制重新渲染屏幕即可获取完整数据的方法吗?我已经尝试异步使用get 命令,但这似乎并没有改变任何东西。

Firebase layout picture

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
  }, []);

结果:
渲染 1:

null
Array []

渲染 2:

cid # This is correct
Array []

渲染 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",
  },
]

【问题讨论】:

    标签: javascript firebase react-native firebase-realtime-database expo


    【解决方案1】:

    您需要将对 setData 的调用移动到 onValue 处理程序中:

    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); // ?
        });
      });
    

    如果您将它留在回调之外,它将在调用 fetchedData.push(...) 之前运行。最简单的检查方法是在两行都设置断点并在调试器中运行,或者添加一些日志记录并检查输出的顺序。

    有关此问题的详细说明,请参阅:Why Does Firebase Lose Reference outside the once() Function?(pre v9,但无论版本如何,行为都是完全相同的)

    【讨论】:

    • 是的,这对我有用。结合@frank-van-puffelen 的建议以及将第二个onValue 命令移到第一个命令中,得到了一个完美运行的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多