eeg*_*per 4 node.js firebase google-cloud-functions google-cloud-firestore
我是 firebase 云函数的新手,我想在集合更改特定文档的字段时更新集合username中某些文档的字段。我使用以下代码来做到这一点:postsusersusername
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);
}
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常。posts集合中的用户名正在正确更改。但是,一段时间后,云功能日志显示此日志:Function execution took 60002 ms, finished with status: 'timeout'。如何解决?如果我必须更新数百万个文档posts集合,这个功能会成为问题吗?
Ren*_*nec 16
问题来自于您没有返回update()方法返回的 Promise ,因此 Cloud Function 不会被告知工作已完成并运行到超时。
如果您必须更新“posts收集中的数百万个文档”,还可能发生的情况是,云功能在您的更新全部完成之前结束。这更烦人!
我建议您观看 Firebase视频系列中名为“Learn JavaScript Promises”的 3 个视频,这些视频解释了为后台触发函数返回 Promise 的关键点。
以下代码应该可以工作。请注意,我使用了批处理写入,它专门用于多个写入操作。
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 batch.commit();
}
});
} else {
return null;
}
});
Run Code Online (Sandbox Code Playgroud)
请注意,批量写入最多可包含 500 个操作。如果您计划更新超过 500 个文档,则可以Promise.all()改为使用,如下所示:
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 {
const promises = []
querySnapshot.forEach(doc => {
promises.push(doc.ref.update({ username: `${newUsername}` }));
});
return Promise.all(promises);
}
});
} else {
return null;
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2525 次 |
| 最近记录: |