我是firebase云函数的新手,当users
集合更改了某个文档的username
字段时,我想更新posts
集合中某些文档的username
字段,我使用以下代码来完成此操作:
exports.updateProfileUsername = functions.firestore
.document('users/{userId}')
.onUpdate((change, context) =>
{
const {userId} = context.params;
var newUsername = change.after.data().username;
var previousUsername = change.before.data().username;
if (newUsername.localeCompare(previousUsername) !== 0)
{
let postCollectionRef = db.collection('posts');
let postQuery = postCollectionRef.where('userId', '==', `${userId}`);
return new Promise((resolve, reject) =>
{
updateUsernameDocuments(postQuery, reject, newUsername);
});
}
});
function updateUsernameDocuments(query, reject, newValue)
{
query.get()
.then((snapshot) =>
{
if (snapshot.size === 0)
{
return 0;
}
return snapshot.docs.forEach((doc) =>
{
doc.ref.update({username : `${newValue}`});
});
}).catch(reject);
}
这段代码运行良好。posts
集合中的用户名更改正确。但是,一段时间后,云函数日志显示以下日志:Function execution took 60002 ms, finished with status: 'timeout'
。如何解决这个问题?如果我必须更新posts
集合中的数百万个文档,这个函数会有问题吗?
1条答案
按热度按时间wydwbb8l1#
问题源于您没有返回
update()
方法返回的Promise,因此云函数没有被告知工作已完成,并且运行到超时。还可能发生的是,如果你必须更新“
posts
集合中的数百万个文档”,云函数在你的更新全部完成之前就结束了,这更烦人!我建议您观看Firebase video series中名为“学习JavaScript承诺”的3个视频,其中解释了返回后台触发函数的承诺的关键点。
下面的代码应该可以工作。注意,我使用了一个批处理写,它特别专用于多个写操作。
请注意,批处理写入最多可以包含500个操作。如果计划更新500个以上的文档,则可以改用
Promise.all()
,如下所示: