【问题标题】:How to save firebase returned data to a variable如何将firebase返回的数据保存到变量中
【发布时间】:2020-01-04 04:04:38
【问题描述】:

我正在为我的 React Native 应用程序编写代码,但我无法从 firebase.firestore().collection("test_data").doc(ID) 循环之外的 firebase 返回中获取数据。每当我在循环之后检查 dataArray 变量时,它都是空的。如果我在循环中检查它,数据就在那里。我认为这是一个范围问题,但我就是不明白。我也不能在循环内调用任何用户定义的函数。

    try {
      let dataArray = [];
      // get the document using the user's uid
      firebase.firestore().collection("users").doc(uid).get()
      .then((userDoc) =>{
        // if the document exists loop through the results
        if (userDoc.exists) {
          data = userDoc.data().saved_data; // an array store in firebase

          data.forEach(ID => { // loop through array

            firebase.firestore().collection("test_data").doc(ID).get()
            .then((doc) => {
              dataArray.push(doc.data().test_data);
              console.log(dataArray) // the data shows
            })
              console.log(dataArray) // the data does not show
          })

        }
      })
    } 
    catch (error) {

    }
  }

【问题讨论】:

    标签: javascript reactjs firebase google-cloud-firestore


    【解决方案1】:

    您正在循环执行异步调用,因此您的最终 console.log 将在收到数据之前触发。您的第一个 console.log 仅在收到数据后触发。

    所以代码可以运行,但函数(promise)将在从您的 firebase 调用收到所有数据之前解析(未定义或无效)。

    如果你想返回数组给调用者,你可以这样做:

    function getDataFromServer() {
      // get the document using the user's uid
      return firebase.firestore().collection('users').doc(uid).get().then(userDoc => {
        // now we're returning this promise
    
        const dataArray = []; // can move this to lower scope
        // if the document exists loop through the results
    
        if (userDoc.exists) {
          const savedData = userDoc.data().saved_data; // an array store in firebase
    
          return Promise.all(
            // wait for all the data to come in using Promise.all and map
            savedData.map(ID => {
              // this will create an array
              return firebase.firestore().collection('test_data').doc(ID).get().then(doc => {
                // each index in the array is a promise
                dataArray.push(doc.data().test_data);
                console.log(dataArray); // the data shows
              });
            })
          ).then(() => {
            console.log(dataArray);
            return dataArray; // now data array gets returned to the caller
          });
        }
    
        return dataArray; // will always be the original empty array
      });
    }
    

    现在函数返回一个数组的承诺,所以你可以这样做......

    const dataArray = await getDataFromServer()

    getDataArrayFromServer().then(dataArray => {...})

    【讨论】:

    • @blacKnight 再次查看这段代码时,我意识到一件事是,dataArray 可能会以不同于在服务器上的排序方式对数据进行排序。一旦我们收到每条数据,我们就会推送到 dataArray,但是 ID 2 的数据可能会在 ID 1 之前返回,所以它会首先被推送。您是否需要保留服务器上数据的顺序?改变并不难,但如果它对你不重要,我会保持原样。
    • no 顺序无关紧要。 ID 用作另一个 Collection 中数据的键。再次感谢您的帮助!
    猜你喜欢
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    相关资源
    最近更新 更多