我正在尝试使用 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/