如何从Firestore数据库中的云功能更新多个文档?
我是Firebase云功能的新手,我想在username
集合更改特定文档的posts
字段时,从users
集合更新某些文档的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
集合中的数百万个文档,此功能是否会有问题?
问题出在您没有返回update()
方法返回的Promise的事实,因此没有通知Cloud Function该工作已完成并且正在超时。
以下代码应该起作用。请注意,我使用了batched write,它专门用于多重写入操作。
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) {
const postCollectionRef = db.collection('posts');
const postQuery = postCollectionRef.where('userId', '==', `${userId}`);
return postQuery.get()
.then(querySnapshot => {
if (querySnapshot.empty) {
return null;
} else {
let batch = db.batch();
querySnapshot.forEach(doc => {
batch.update(doc.ref, { username: `${newUsername}` });
});
return batchmit();
}
});
} else {
return null;
}
});
注意,批量写入最多可包含500个操作。如果您打算更新500多个文档,则可以改用Promise.all()
。