【问题标题】:Waiting for async call to finish so I can use the result, its not working?等待异步调用完成,以便我可以使用结果,它不起作用?
【发布时间】:2021-01-03 01:55:42
【问题描述】:

我尝试使用 .get() 查询 Firestore:

//Cloud function to perform leaderboard calculation
exports.scheduledLeaderboardFunction = functions.pubsub.schedule('00 21 * * *')
  .timeZone('America/Los_Angeles') 
  .onRun(async (context) => {

    var globalPostsArray = [];

    try {
        await admin.firestore()
        .collection('globalPosts')
        .get()
        .then((querySnapshot) => {

            if(querySnapshot.exists) {
    
                querySnapshot.forEach((res) => {

                const { 
                    
                    //Fields
                    //Removed

                    } = res.data();
        
                    globalPostsArray.push({
                        
                        //Fields
                        //Removed

                    });
                });
            }
            else {
                throw new Error("Data doesn't exist") <-------- This error is thrown
            }
            return null
        })
        .then(() => {
            if (globalPostsArray.length > 0) {
                console.log(globalPostsArray)
            }
            else {
                throw new Error("length not greater than 0")
            }
            return null;
        })
    }
    catch(error) {
        console.log(error);
    }

    return null;

});

但在 firebase 云日志中,我打印出以下错误:

Error: Data doesn't exist 

这意味着当我使用 .get() 时 querySnapshot 不存在(抛出错误)。

globalPosts,我正在查询的集合,不为空

如果我可以让 .get() 工作,那将解决我的问题,因为我不等待更新,而这正是 .onSnapshot() 的好处。

总结:onSnapshot() 用于从 Firestore 获取数据,但我不能使用 .then() 来等待数据,因此我可以完成工作。 get() 不起作用,但如果它起作用,我可以使用 .then() 等待收集。

如何解决我的问题?

编辑:将功能更改为此,但仍然无法正常工作

//Cloud function to perform leaderboard calculation
exports.scheduledLeaderboardFunction = functions.pubsub.schedule('00 21 * * *')
  .timeZone('America/Los_Angeles') 
  .onRun(async (context) => {


    try {
        await admin.firestore().collection('globalPosts').orderBy("date_created", "desc")
        .get()
        .then(function(querySnapshot) {
            if(querySnapshot) {
                querySnapshot.forEach(function(doc) {
                    // doc.data() is never undefined for query doc snapshots
                    console.log(doc.id, " => ", doc.data());
                });
                return null
            }
            else {
                throw new Error("Data doesn't exist")
            }
        })
    }
    catch(error) {
        console.log(error);
    }


    return null;

});

证明 globalPosts 不为空:

同样的错误:

Error: Data doesn't exist 

【问题讨论】:

  • 传递给onSnapshot 的函数发生在未来的某个时间点,即最终获取数据时,然后在数据更改时可能更多。您在该回调中有来自 Firestore 的数据,为什么不能在 onSnapshot 中进行计算?
  • 等一下,这是云功能吗?您无法打开侦听器并让它在无服务器功能中保持打开状态。函数不应该是持久的。
  • 是的,我首先使用了 onSnapshot,但后来认为 get() 可能是要走的路。使用 get(),我的请求抛出了错误。 @windowsill 真的很奇怪,因为我在前端的许多其他地方都使用了 get() 并且没有遇到这个问题,但是我在云函数中使用 get() 时遇到了问题

标签: node.js react-native google-cloud-firestore google-cloud-functions


【解决方案1】:

我认为您使用 .get() 走在正确的轨道上,但不要混用异步语法。

  const shortSnapshot = await firebase.firestore()
    .collection("stuff")
    .where("stuff", "==", "new")
    .limit(1)
    .get();

  if (shortSnapshot.empty) {
    console.error("No stuff");
    return response.sendStatus(404);
  }

  console.log(shortSnapshot.docs[0].data());

【讨论】:

  • shortSnapshot 会是一个包含整个集合的数组吗?
  • 不,它是 Firestore 查询结果对象。您可以在 Firestore 文档中找到更多信息,但您可以访问上述查询结果中的每个文档 (snapshot.docs.map(d =&gt; d.data()))。
  • 即使数据库不是空的,仍然会因为没有东西而出现错误
【解决方案2】:

.onSnapShot 没有 .then - 它附加一个侦听器函数,并同步返回,没有数据 - 它不返回承诺。

您创建并传递的匿名函数 - 它以 (querySnapshot) =&gt; { 开头,使用 querySnapshot 调用,因为它的参数 when 触发了侦听器。从代码的其他部分来看,您正在尝试云功能?作为一般规则,侦听器不是云函数的正确方法,因为这些函数的生命周期很短。

如果您的集合 'globalPosts' 为空,您所显示的消息正是预期的结果 - 并且您在此处没有显示任何内容来表明这是一个错误。

【讨论】:

  • globalPosts 不为空 - 抱歉,将在问题中添加说明。但我现在明白 onSnapshot 不是正确的方法, .get() 是。无论如何,.get() 不起作用
  • 您已经展示了文档,但不是其中包含的内容。如果你“排序”,或者如果你包含一个“where”子句,它只会返回这些字段的文档。如果您没有“看到”它(无论是在 Firestore 控制台还是 console.log 消息中),您就不会“知道”它。
  • 我已经解决了这个问题。添加了答案。还是谢谢。
【解决方案3】:

删除 try, catch 解决了我的问题!

await admin.firestore().collection('globalPosts').orderBy("date_created", "desc")
.get()
.then(function(querySnapshot) {
    if(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            // doc.data() is never undefined for query doc snapshots
            console.log(doc.id, " => ", doc.data());
        });
        return null
    }
    else {
        throw new Error("Data doesn't exist")
    }
})

“数据不存在”的错误不再是问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 2012-05-04
    • 2019-10-30
    相关资源
    最近更新 更多