javascript - 用于循环异步等待的 Firebase 函数

标签 javascript firebase google-cloud-functions

我正在尝试使用 Firebase Functions 执行一个理论上相对简单的函数。

具体:

  • + 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' expression is only allowed within an async function.

const devices = await devicesRef.get();

但即使我得到它没有错误,它似乎也不起作用。 Firebase 函数日志显示:

4:45:26.207 PM gcIncrement Function execution took 444 ms, finished with status: 'ok' 4:45:25.763 PM gcIncrement Function execution started

所以它似乎按预期运行,但未按预期履行代码。有任何想法吗?谢谢!

最佳答案

所有对 await 的使用都必须发生在标记为 async 的函数主体内。您的函数 sendGCNotification 不是异步的。您必须将其标记为异步,并确保已等待其中的任何 promise ,或者返回一个在所有异步工作完成后解析的 promise 。

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

如果您想了解有关 Cloud Functions 代码中的 Promise 和 async/await 的更多信息,我建议您使用我的 video series 。具体来说,标题为“async/await 如何与 TypeScript 和 ECMAScript 2017 配合使用?”。即使您不使用 TypeScript,async/await 也会以相同的方式工作。

关于javascript - 用于循环异步等待的 Firebase 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54082691/

相关文章:

javascript - 运行 Selenium Webdriver (Python) 测试时如何加载 Firefox 并禁用 javascript?

javascript - 如何获取div当前滚动位置?

javascript - 如何使用 JavaScript 解码 Node-Red 中 msg.payload 内的 HTML 实体?

android - 在 Firebase 数据库中添加数据

javascript - jquery大图缩略图问题

swift - 打印特定的子 Firebase 数据库

android - 如何在Firebase中保存音频文件

javascript - Firebase 函数 admin.database() 事务中的 null 参数

javascript - 如何将客户端 Firebase Cloud 消息 token 获取到 Google Cloud 功能?

google-cloud-functions - ingressSettings = ALLOW_INTERNAL_ONLY 时如何从 Google Cloud Scheduler 调用 Google Cloud Function?