代码之家  ›  专栏  ›  技术社区  ›  Simon

用于循环异步等待的firebase函数

  •  0
  • Simon  · 技术社区  · 5 年前

    我正在尝试用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=等待devicesRef.get();

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

    4:45:下午26.207点 GC增量 函数执行耗时444毫秒,完成状态:“OK” 4:45:下午25.763点 GC增量 函数执行已开始

    因此,它似乎按预期运行,但没有按预期完成代码。有什么想法吗?谢谢您!

    1 回复  |  直到 5 年前
        1
  •  2
  •   Doug Stevenson    5 年前

    所有用途 await 必须出现在标记的函数的主体中 async . 你的功能 sendGCNotification 不是异步的。您必须将其标记为异步,并确保其中的任何承诺都已被等待,或者返回一个在完成所有异步工作时解决的承诺。

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

    如果您想进一步了解云函数代码中的承诺和异步/等待,我建议您使用 video series .具体来说,标题为“Async/Await如何与TypeScript和EcmaScript 2017一起工作?”。即使您不使用typescript,async/await的工作方式也是一样的。