Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/407.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 具有子集合的Firestore查询_Javascript_Firebase_Google Cloud Functions_Google Cloud Firestore - Fatal编程技术网

Javascript 具有子集合的Firestore查询

Javascript 具有子集合的Firestore查询,javascript,firebase,google-cloud-functions,google-cloud-firestore,Javascript,Firebase,Google Cloud Functions,Google Cloud Firestore,这是对Firebase的限制还是我做错了?直到我添加了 dB。集合(‘用户’)。代码中的doc(FrEnDID).GETH(…)/。提前谢谢 const db = admin.firestore(); const friendRef = db.collection('users').doc(id).collection('friends'); friendsList = []; friendRef.get().then((onSnapshot) => { if (!onSnap

这是对Firebase的限制还是我做错了?直到我添加了<代码> dB。集合(‘用户’)。代码中的doc(FrEnDID).GETH(…)/<代码>。提前谢谢

const db = admin.firestore();
const friendRef = db.collection('users').doc(id).collection('friends');

friendsList = [];

friendRef.get().then((onSnapshot) => {
    if (!onSnapshot.empty) {
        onSnapshot.forEach((friend) => {

            const friendId = String(friend.data().person_id);

            db.collection('users').doc(friendId).get().then((result) => {
                const firstName = String(result.data().name.first);
                const lastName = String(result.data().name.last);
            })

            const data = {
                personId: friendId,
                firstName: firstName,
                lastName: lastName,
            }

            friendsList.push(data);
        })

        res.send(friendsList);
    } else {
        res.send({
            'message': 'no friends'
        });
    }
}).catch((e) => {
    res.send({
        'error': e
    });
})

数据从Firestore异步加载。这意味着,当您将响应发送回客户端时,数据尚未从Firestore加载

查看这一点的最简单方法是使用一些位置良好的日志记录语句:

console.log("Before getting friend");
db.collection('users').doc(friendId).get().then((result) => {
  console.log("Got friend");
})
console.log("After getting friend");
当您仅运行此代码时,它将打印:

在交朋友之前

结交朋友后

交了朋友

这可能不是您期望日志的顺序。原因是数据可能需要一段时间才能从Firestore返回。因此,它不再阻塞线程,而是继续运行线程,然后在数据可用时调用回调函数。不幸的是,这意味着您的
res.send(friendsList)
最终会向客户端发送一个空列表,因为数据尚未加载

解决方法是使用一组嵌套回调,使用
Promise.all
()或ES6新的
async
/
wait
关键字。对于承诺,代码如下所示:

const db = admin.firestore();
const friendRef = db.collection('users').doc(id).collection('friends');

friendRef.get().then((onSnapshot) => {
  var promises = [];

  onSnapshot.forEach((friend) => {
    const friendId = String(friend.data().person_id);    
    promises.push(db.collection('users').doc(friendId).get());
  });

  Promise.all(promises).then((snapshots) => {
    friendsList = [];
    snapshots.forEach((result) => {
      friendsList.push({
        personId: result.id,
        firstName: result.data().name.first,
        lastName: result.data().name.last,
      });
    });
    res.send(friendsList);
  });
}).catch((e) => {
  res.send({
    'error': e
  });
})

因此,我们首先构建所有友元读取操作的列表,然后在所有这些操作完成后,构建响应并将其发送回。

数据从Firestore异步加载。这意味着,当您将响应发送回客户端时,数据尚未从Firestore加载

查看这一点的最简单方法是使用一些位置良好的日志记录语句:

console.log("Before getting friend");
db.collection('users').doc(friendId).get().then((result) => {
  console.log("Got friend");
})
console.log("After getting friend");
当您仅运行此代码时,它将打印:

在交朋友之前

结交朋友后

交了朋友

这可能不是您期望日志的顺序。原因是数据可能需要一段时间才能从Firestore返回。因此,它不再阻塞线程,而是继续运行线程,然后在数据可用时调用回调函数。不幸的是,这意味着您的
res.send(friendsList)
最终会向客户端发送一个空列表,因为数据尚未加载

解决方法是使用一组嵌套回调,使用
Promise.all
()或ES6新的
async
/
wait
关键字。对于承诺,代码如下所示:

const db = admin.firestore();
const friendRef = db.collection('users').doc(id).collection('friends');

friendRef.get().then((onSnapshot) => {
  var promises = [];

  onSnapshot.forEach((friend) => {
    const friendId = String(friend.data().person_id);    
    promises.push(db.collection('users').doc(friendId).get());
  });

  Promise.all(promises).then((snapshots) => {
    friendsList = [];
    snapshots.forEach((result) => {
      friendsList.push({
        personId: result.id,
        firstName: result.data().name.first,
        lastName: result.data().name.last,
      });
    });
    res.send(friendsList);
  });
}).catch((e) => {
  res.send({
    'error': e
  });
})

因此,我们首先建立一个所有好友阅读操作的列表,然后在所有这些操作完成后,我们构建响应并将其发送回去。

太棒了,它成功了。我现在明白你的解释了。再次感谢。我很想用ES6来做这个。如果您有时间并且不介意的话,可以使用ES6 async/await发送它,这样我就知道了。我将开始学习ES6的谷歌功能。提前谢谢。你好,弗兰克。除了由于某种原因我没有得到
personId:snapshot.id
的输出外,一切正常。我尝试了一些方法:
snapshots.id
result.id
,但也没有成功。这是
onSnapshot.forEach((朋友)的id…
应该是
friend.id
。再次感谢。您的代码没有显示如何初始化
friendId
,因此我假设它是文档id:。如果不是这样,您需要修改解决方案的该部分以满足您的需要。再次感谢@Frankvanpoffelen的帮助。我仍然不知道如何推送文档从Friends collection到friendsList数组的id。我问了一个新问题,因为我认为可能很难在注释中解释它。啊…它应该是
result.id
,我刚刚更新了代码。
result.id
是您加载的文档的id。由于您基于
friendId
加载文档,我它的值将与
friendId
的值相同。太棒了,它成功了。我现在理解了你的解释。再次感谢。我很想使用ES6实现这一点。如果你有时间并且不介意的话,你能用ES6 async/await发送它吗,所以我对它有所了解。我将开始使用谷歌函数学习ES6。提前谢谢。嗨,弗兰克。一切正常ept由于某种原因,我没有得到
personId:snapshot.id
的输出。我尝试了一些方法:
snapshot.id
result.id
,但这也不起作用。这是
onSnapshot.forEach((朋友)的id…
应该是
friend.id
。再次感谢。您的代码没有显示如何初始化
friendId
,因此我假设它是文档id:。如果不是这样,您需要修改解决方案的该部分以满足您的需要。再次感谢@Frankvanpoffelen的帮助。我仍然不知道如何推送文档从Friends collection到friendsList数组的id。我问了一个新问题,因为我认为可能很难在注释中解释它。啊…它应该是
result.id
,我刚刚更新了代码。
result.id
是您加载的文档的id。由于您基于
friendId
加载文档,我t的值将与
friendId
的值相同。