Вот что я пытаюсь сделать с помощью облачной функции Firebase:
-Следить за любым изменением в одном из документов в коллекции 'user'.
-Обновление копий копий userinfo в соответствующих документах в коллекциях 'comment' и 'post'.
Поскольку мне нужно будет запрашивать соответствующие документы и обновлять их сразу, я пишу коды для операций транзакции.
Вот код, который я написал. Он возвращает сообщение об ошибке «Функция вернула неопределенное, ожидаемое обещание или значение».
exports.useInfoUpdate = functions.firestore.document('user/{userid}').onUpdate((change,context) => {
const olduserinfo=change.before.data();
const newuserinfo=change.after.data();
db.runTransaction(t=>{
return t.get(db.collection('comment').where('userinfo','==',olduserinfo))
.then((querysnapshot)=>{
querysnapshot.forEach((doc)=>{
doc.ref.update({userinfo:newuserinfo})
})
})
})
.then(()=>{
db.runTransaction(t=>{
return t.get(db.collection('post').where('userinfo','==',olduserinfo))
.then((querysnapshot)=>{
querysnapshot.forEach((doc)=>{
doc.ref.update({userinfo:newuserinfo})
})
})
})
})
});
Я немного запутался, потому что, насколько я знаю, метод update возвращает обещание? Возможно, я что-то упустил, но я занялся программированием только в ноябре прошлого года, так что не переживайте sh. :)
Любой совет, как решить эту проблему? Спасибо!
РЕДАКТИРОВАТЬ: Опираясь на Renaud отличный ответ, я создал следующий код на случай, если кому-то может понадобиться. Сложность транзакции заключается в том, что одни и те же данные могут храниться под разными индексами или в разных форматах. Например, одна и та же переменная 'map' может храниться под индексом в одной коллекции и как часть массива в другой. В этом случае для каждого документа, возвращаемого по запросу, требуются разные методы обновления.
Я решил эту проблему с помощью методов do c .ref.path, split и switch. Это позволяет применять различные методы обновления в зависимости от имени коллекции. В двух словах, примерно так:
return db.runTransaction(t => {
return t.getAll(...refs)
.then(docs => {
docs.forEach(doc => {
switch (doc.ref.path.split('/')[0]) { //This returns the collection name and switch method assigns a relevant operation to be done.
case 'A':
t = t.update(doc.ref, **do whatever is needed for this collection**)
break;
case 'B':
t = t.update(doc.ref, **do whatever is needed for this collection**)
break;
default:
t = t.update(doc.ref, **do whatever is needed for this collection**)
}
})
})
})
Надеюсь, это поможет!