首页 > 解决方案 > 打开应用程序时未从 Firebase 获取数据

问题描述

我正在尝试从 firebase 获取数据,但是当应用程序加载时它返回空值,但是如果我在该文件上编辑某些内容,即使是注释行,然后数据加载和应用程序运行,我希望当应用程序打开时所有数据都应该在那里从 firebase 运行应用程序。以及如何以相反的顺序排列“grabbedData”尝试了grabbedData.reverse()但没有工作。

  const Getdata = async () => {
    let grabbedData = [];

    await firebase
      .database()
      .ref(`/users/`)
      .orderByKey()
      .on("value", (snapshot, key) => {
        // console.log("snapshot....", snapshot);
        grabbedData.push(snapshot.val());
      });
    setUserdata(grabbedData);
    console.log("grabbedData", grabbedData); // empty value here :(
    if (grabbedData) {
      let getfranchiseuid = "";
      Object.keys(grabbedData).map(function (key) {
        let y = grabbedData[key];
        Object.keys(y).map(function (key2) {
          let x = y[key2];
          if (key2 === uid) {
            getfranchiseuid = x.franchiseuid;
          }
        });
      });

      if (getfranchiseuid) {
        let customerList1 = [];
        firebase
          .database()
          .ref(`/serviceProvider/${getfranchiseuid}/franchise/customers`)
          .orderByKey()
          .on("value", (snapshot) => {
            customerList1.push(snapshot.val());
          });
        setCustomerList(customerList1);
        console.log("customerList1customerList1", customerList1);
      }
    }
  };

  useEffect(() => {
    var unsubscribe = firebase.auth().onAuthStateChanged(function (user) {
      if (user) {
        storeUser({ user });
        setUser(user);
        setEmail(user.email);
        setUid(user.uid);
      } else {
        // No user is signed in.
      }
    });
    unsubscribe();
    Getdata();
  }, []);

标签: javascriptreactjsfirebase-realtime-databasefirebase-authentication

解决方案


数据从 Firebase 异步加载。由于这可能需要一些时间,因此您的主要 JavaScript 代码将继续运行,以便用户可以在数据加载时继续使用应用程序。然后,当数据可用时,将使用该数据调用您的回调。

这在您的代码中意味着(例如)现在您在运行setUserdata之前被调用grabbedData.push(snapshot.val()),因此您正在设置任何空的用户数据。您可以通过在代码上设置一些断点并在调试器中运行它,或者通过添加日志记录并检查其输出的顺序来最容易地看到这一点。

console.log("1");
await firebase
  .database()
  .ref(`/users/`)
  .orderByKey()
  .on("value", (snapshot, key) => {
    console.log("2");
  });
console.log("3");

运行此代码时,输​​出将是:

1

3

2

这可能不是您所期望的,但它完全正确并且确实解释了您的问题。


解决方案总是相同的:任何需要数据库数据的代码都必须回调中,或者从那里调用。

例如:

await firebase
  .database()
  .ref(`/users/`)
  .orderByKey()
  .on("value", (snapshot, key) => {
    grabbedData.push(snapshot.val());
    setUserdata(grabbedData);
  });

这将确保setUserdata在您更新grabbedData.


由于您有更多的代码依赖于grabbedData,因此它也必须在回调中。if (grabbedData) {因此需要移动整个街区,可能还有其他街区。如果您继续应用上述解决方案,代码将开始工作。

对于不熟悉调用异步云 API 的开发人员来说,这是一个非常常见的问题,因此我强烈建议您阅读以下一些其他答案:


推荐阅读