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 - 如何在 Chrome 应用程序开发中枚举已连接的 USB 和 Wi-Fi 设备

javascript - 使用带有 css 转换的 javascript .style

firebase - 云Firestore : how to fetch a document reference inside my collection query and map it as a JSON value?

firebase - 在谷歌云功能中找不到包 "firebase.google.com/go"

java - 在jsp中添加后退按钮

javascript - JS 或 jQuery - 从数组中删除元素

swift - 如何使用 swift 4 将 int 变量插入到 firebase

javascript - 如何将 expo 应用程序连接到 google firestore?

node.js - GCP 云函数和 BigQuery : Row is inserted but all columns are null

javascript - 如何使用 Cloud 函数从 Cloud firestore 触发器中的顶级文档访问数据?