循环异步的Firebase函数等待



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

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

4:45:26.207 PMgc增量函数执行耗时444毫秒,已完成,状态为"ok"下午4:45:25.763gc增量功能执行启动

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

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

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

如果你想了解更多关于云函数代码中的promise和async/await的信息,我建议你使用我的视频系列。特别是题为"异步/等待如何与TypeScript和ECMAScript 2017一起工作?"的文章。即使您没有使用TypeScript,async/await也以同样的方式工作。

最新更新