我确实拥有这个非常混乱的Firebase函数。
exports.getAverage = functions.firestore
.document('users/{userId}/days/{day}')
.onUpdate((snapshot, context) => {
let averages = {};
let temp = [];
let dayRefDoc = admin.firestore().collection(`users/${context.params.userId}/days`)
return dayRefDoc.get().then(inner => {
console.log(inner.docs);
for (doc of inner.docs) {
console.log(doc);
return doc.ref.collection('session').get().then(session => {
session.docs.forEach(doc => temp.push(parseInt(doc.data().duration)))
})
}
}).then(() => {
console.log(temp);
averages["sessionTime"] = (temp.reduce(function (a, b) { return a + b; }, 0)) / temp.length;
return admin.firestore().collection('users').doc(context.params.userId).get().then(inner => {
return inner.ref.update({ averageSessionTime: averages.sessionTime })
})
})
})
这里的想法是我数据库中的每个user
都有一个days
的子集合,并且每天都有一个名为session
的子集合。我想整天浏览每个session
文档,并计算一个名为duration
的变量,然后获取整天所有会话的所有持续时间的平均值。
获得平均值并不困难。我现在正在兑现诺言。特别是,使函数可以迭代特定用户的每个days
子集合。我的解决方案现在适用于迭代的第一个文档,但无法获取下一个文档,大概是因为doc.ref.collection('session').get().then()
是它自己的承诺,而我正在对该承诺进行回报,这导致它被破坏在for (doc of inner.docs)
循环之外。
我是否正确地认为这是问题所在?我觉得使用循环创建这些承诺反而是一个坏主意,那么做这样的事情的预期做法是什么?
答案 0 :(得分:0)
我认为您的目标正确。我的第一个想法:
let docs = [];
for (doc of inner.docs) {
console.log(doc);
docs.append( doc.ref.collection('session').get() )
}
Promise.all(docs).then( values => {...} );
因此,您将在列表中收集所有诺言,等待所有诺言得到解决,然后对结果执行任何您想做的事情。