【发布时间】:2019-03-04 15:01:06
【问题描述】:
我试图弄清楚如何从 Angular 6 / typescript 应用程序将事务写入 firebase 数据库。
我用作指导的一个工作示例如下:
const transactions = [];
return db.runTransaction(function(transaction) {
// const promises = [];
descriptionsInDB.forEach(dbDescription => {
if (dbDescription.matched === false) {
// item wasn't found, so add the item to the transaction.
const phraseItem: PhrasesDB = {
query: dbDescription.description,
updatedAt: Date.now(),
createdAt: Date.now(),
workflows: {
[workflowId]: true
}
};
const newPhrasesRef = phrasesCol.doc();
transactions.push(transaction.set(newPhrasesRef, phraseItem));
} else {
if (dbDescription.data.workflows && dbDescription.data.workflows[workflowId]) {
// do nothing, this phrase is already part of the record.
} else { // update the workflows that are part of the record.
const workflows = {
workflows: {
[workflowId]: true
}
};
const phrasesRef = phrasesCol.doc(dbDescription.dbId);
transactions.push(transaction.update(phrasesRef, workflows));
}
}
});
return Promise.all(transactions);
})
我确定的关键部分如下:
1) 创建一个数组来保存您的交易: const transactions = [];
2) 开始事务:return db.runTransactions(function(transaction) {…
3) 使用事务执行数据库查询:transaction.set(newPhraseRef,phraseItem);
4) 将查询返回的交易推送到交易数组:transactions.push(transaction.set(newPhraseRef,phraseItem));
5) 返回一个带有事务数组的承诺:return Promise.all(transaction);
如果我有这个权利,那么我应该能够将这个公式应用于我正在尝试编写的事务,并且它应该可以工作:
const pendingRef = `Pending/${req.query.inviteId}`;
const acceptance = {
'cryptoInvitationAcceptance': req.body.cryptoInvitationAcceptance,
'reason': (req.body.reason !== undefined ? req.body.reason : '')
}
return db.runTransaction(function(t) {
const transArray = [];
const docRef = db.collection('Pending').doc(req.query.inviteId);
transArray.push(t.set(docRef, acceptance));
return Promise.all(transArray);
}).then(result => {
console.log('result = ', result);
}).catch(err => {
console.log('err = ', err);
});
但它总是进入 catch 块并打印出消息:
err = 错误:你必须在你的 transaction()-callback 中返回一个 Promise。
但我正在回报一个承诺,不是吗?这行:return Promise.all(transArray) 是我要返回的承诺。没有?
【问题讨论】:
-
在您发布的示例中,
transactions[]用于从forEach循环中收集承诺。这就是他们使用Promise.all的原因。由于您只执行一项操作,因此您应该能够在没有transArray[]的情况下使用return t.set(docRef, acceptance)。但是,这不应该解决您的问题。
标签: typescript firebase promise transactions angular6