当前位置: 首页 > 知识库问答 >
问题:

用于循环异步的Firebase函数正在等待

魏成济
2023-03-14

我试图用Firebase函数做一个理论上相对简单的函数。

具体地说:

>

  • 向所有用户的实时数据库变量添加+1

    向所有用户发送通知

    我仍然在努力理解async/await,这可能就是为什么我在这个问题上如此纠结的原因。

    我正在做的是:

     exports.gcIncrement = functions.database
      .ref('gthreads/{threadId}/messages/{messageId}')
      .onCreate(async (snapshot, context) => {
    
        const data = snapshot.val();
        const threadId = context.params.threadId;
        const uid = context.auth.uid;
        
        adb.ref('gchats/' + threadId).once('value').then(async (gchatData) => {
        const parent = gchatData.val();
        incrementUser(parent.users, uid, threadId); //parent.users is an object with 1-30 users.
        sendGCNotification(parent.users, data);
        return true;
      }).catch(error => console.log(error))
    });
    

    然后就有了incrementuser:

    function IncrementUser(array, uid, threadId) {
        for (const key in array) {
          if (key != uid) {
            const gcMessageRef =
            adb.ref('users/' + key + '/gthreads/' + threadId + '/' + threadId+'/unread/');
            gcMessageRef.transaction((int) => {
              return (int || 0) + 1;
          }
        }
      }
    

    和函数sendgcnotification:

      function sendGCNotification(array, numbOfMsg, data) {
        let payload = {
          notification: {
            title: 'My App - ' + data.title,
            body: "This is a new notification!",
          }
        }
        const db = admin.firestore()
        for (const key in array) {
          if (!data.adminMessage) {
            if (array[key] === 0) {
    
              const devicesRef = db.collection('devices').where('userId', '==', key)
    
              const devices = await devicesRef.get();
              devices.forEach(result => {
                const tokens = [];
                const token = result.data().token;
                tokens.push(token)
    
                return admin.messaging().sendToDevice(tokens, payload)
              })
    
            }
          }
        }
      }
        
    

    我当前得到的错误是:

    “Await”表达式仅允许在异步函数中使用。

    const devices=await devicesref.get();

    但即使我得到它没有错误,它似乎不工作。Firebase Functions日志显示:

    4:45:26.207 PM gcIncrement函数执行时间为444 ms,已完成,状态为“OK”4:45:25.763 PM gcIncrement函数执行开始

    所以它看起来像预期的那样运行,但没有像预期的那样实现代码。有什么想法吗?谢谢!

  • 共有1个答案

    劳华灿
    2023-03-14

    await的所有用法都必须发生在标记为async的函数主体中。您的函数sendgcnotification不是异步的。您必须将其标记为异步,并且还要确保它中的任何承诺都是等待的,或者返回一个承诺,当所有异步工作完成时,该承诺就会解析

    此外,在incrementuser中,您没有处理GCMessageRef.transaction()返回的承诺。您需要处理从所有异步工作中生成的每个承诺,并确保它们都是从顶级函数返回或等待的最终承诺的一部分。

    如果您想了解更多关于Cloud函数代码中的promises和Async/Await的信息,我建议您使用我的视频系列。具体地说,一篇题为“Async/Await如何与TypeScript和ECMAScript 2017一起工作?”的文章。即使不使用TypeScript,async/await也以同样的方式工作。

     类似资料:
    • 本文向大家介绍JavaScript 异步等待循环,包括了JavaScript 异步等待循环的使用技巧和注意事项,需要的朋友参考一下 示例 在循环中使用异步等待时,您可能会遇到其中一些问题。 如果您只是尝试在内部使用await forEach,则会抛出Unexpected token错误。 这是因为您错误地将箭头功能视为一个块。该await会在回调函数,这是不是上下文async。 解释器可以防止我们

    • 问题内容: 我如何访问传递给fs.lstat函数的变量? 问题答案: 这是使用而不是for循环迭代值的完美理由。 另外,您可以使用@Aadit建议的闭包:

    • 我在一个循环中调用了一个异步函数来发送电子邮件,但是有一段时间控件没有返回,也没有发送电子邮件,但是主UI线程完成了。 当我把等待任务。WhenAll(发送电子邮件任务);循环内的线工作正常,但当我把这条线放在循环外时,它不工作,但实际上它应该在循环外。我在sendEmail方法中有很多异步方法,所以我认为有些线程彼此重叠。任何线索。

    • 问题内容: 在循环中使用/ 是否有任何问题?我试图遍历文件数组和每个文件的内容。 这段代码确实有效,但是这可能会出问题吗?我让某人告诉我,您不应该在这样的高阶函数中使用/ ,所以我只是想问一下这是否有问题。 问题答案: 确保代码确实有效,但是我很确定它不会实现您期望的功能。它只会触发多个异步调用,但此后函数会立即返回。 顺序阅读 如果要顺序读取文件, 则不能使用。只需使用现代循环即可,该循环将按预

    • 问题内容: 我有以下代码: 是与Memcached数据库的连接。可以想象,回调函数是异步的,因此可以在for循环已结束时执行。同样,以这种方式调用时,它始终使用for循环的最后一个值。 我用这种方式尝试关闭 但是显然,这再次使用了for循环索引的最后一个值。 我也尝试在for循环之前声明一个函数,如下所示: 然后打电话 但同样没有成功,返回值始终是for循环的最后一个值。 谁能告诉我关闭有错吗?我

    • 我正试图将图像上传到firebase存储,但调用该函数时,未执行wait以获取url。我错过了什么? 看看这个其他主题,我发现问题可能是“然后”,但我如何设置代码以等待url? 异步/等待/然后飞镖/颤振 谢谢