Проблема заключается в том, что вы не возвращаете обещание, возвращенное методом update()
, поэтому облачная функция не информируется о том, что работа выполнена, и выполняется до истечения времени ожидания.
ЧтоТакже может произойти, если вам нужно обновить «миллионы документов в posts
коллекции», если облачная функция завершает работу до , все ваши обновления завершены. Это еще более раздражает!
Я бы посоветовал вам посмотреть 3 видеофильма под названием «Изучите обещания JavaScript» из серии видеороликов Firebase , которые объясняют эту ключевую точку возврата обещаний для функций, запускаемых в фоновом режиме.
Следующий код должен работать. Обратите внимание, что я использовал пакетную запись , которая специально предназначена для нескольких операций записи.
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;
}
});
Обратите внимание, что пакетная запись может содержать до 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;
}
});