如何将 Firebase 返回的数据保存到一个变量中

huangapple go评论74阅读模式
英文:

How to save firebase returned data to a variable

问题

我正在为我的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; // 存储在Firebase中的数组

          data.forEach(ID => { // 遍历数组
            
            firebase.firestore().collection("test_data").doc(ID).get()
            .then((doc) => {
              dataArray.push(doc.data().test_data);
              console.log(dataArray) // 数据显示
            })
              console.log(dataArray) // 数据不显示
          })
          
        }
      })
    } 
    catch (error) {
      
    }
  }
英文:

I am coding for my React Native app and I am having trouble getting the data from the firebase return outside of the firebase.firestore().collection("test_data").doc(ID) loop. Whenever I check the dataArray variable after the loop it is empty. If I check it within the loop, the data is there. I think that it is a scope problem, but I just do not understand it. I also cannot call any user defined functions inside of the loop.

    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) {
      
    }
  }

答案1

得分: 6

你正在通过异步调用进行循环,因此在数据接收之前,最终的 console.log 将触发。只有在数据接收后,第一个 console.log 才会触发。

因此,代码是有效的,但是该函数(promise)将在从 Firebase 调用中接收到所有数据之前解析(为 undefined 或 void)。

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

function getDataFromServer() {
  // 使用用户的 uid 获取文档
  return firebase.firestore().collection('users').doc(uid).get().then(userDoc => {
    // 现在我们返回这个 promise

    const dataArray = []; // 可以将此移到较低的作用域
    // 如果文档存在,则遍历结果

    if (userDoc.exists) {
      const savedData = userDoc.data().saved_data; // 存储在 Firebase 中的数组

      return Promise.all(
        // 使用 Promise.all 和 map 等待所有数据传入
        savedData.map(ID => {
          // 这将创建一个数组
          return firebase.firestore().collection('test_data').doc(ID).get().then(doc => {
            // 数组中的每个索引都是一个 promise
            dataArray.push(doc.data().test_data);
            console.log(dataArray); // 显示数据
          });
        })
      ).then(() => {
        console.log(dataArray);
        return dataArray; // 现在数据数组会返回给调用者
      });
    }

    return dataArray; // 始终是原始的空数组
  });
}

现在该函数返回一个数组的 promise,因此你可以这样做:

const dataArray = await getDataFromServer()

或者

getDataArrayFromServer().then(dataArray => {...})
英文:

You're looping through asynchronous calls, so your final console.log will trigger before the data has been received. Your first console.log only triggers after the data has been received.

So the code is working, but the function (promise) will resolve (as undefined, or void) before all the data has been received from your firebase calls.

If you want to return the array to the caller, you could do something like this:

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

Now the function returns the promise of an array, so you could do...

const dataArray = await getDataFromServer()

or

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

huangapple
  • 本文由 发表于 2020年1月4日 12:04:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/59587780.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定