当前位置: 首页 > 知识库问答 >
问题:

必须返回promise的firebase事务

陶裕
2023-03-14

我试图弄清楚如何从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)开始事务:返回db.runtransactions(function(transactions){…

3)使用事务:transaction.set(newPhraseRef,phraseItem)执行DB查询;

4)将查询返回的事务推送到事务数组:transactions.Push(transaction.set(newPhraseRef,phraseItem));

5)用事务数组返回一个承诺:Return promission.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()-回调中返回一个承诺。

但我是在回报一个承诺,不是吗?行:return promission.all(transArray)是我返回的承诺。没有?

共有1个答案

米飞龙
2023-03-14

请阅读事务集()的文档-它不返回承诺。这可能会使Firestore SDK感到困惑,因为您返回的是一组不是承诺的东西的promise.all()。所以它可能认为您返回了一个错误。

您可能根本不需要从事务处理程序函数返回任何东西。只需调用set()并完成它。如果希望通过runTransaction返回的promise将该值传递给runTransaction的调用方,则只需要从事务处理程序返回一些内容。

顺便说一句,在第一个示例中,不应该将承诺收集到在处理程序函数外部定义的数组中。如果事务处理程序运行了多次,这可能会导致问题。正如我链接到的文档所说:

不要修改事务函数中的应用程序状态。这样做会引入并发问题,因为事务函数可以多次运行,并且不能保证在UI线程上运行。

事务外部的数组将被视为“应用程序状态”,因为它不在函数本身内部。

 类似资料:
  • 我正在创建一个谷歌数据流管道使用Apache梁2. x 基本上,我有一个文本文件,每一行都包含一个英语句子。 我试图调用谷歌NLP(情感)API为每一个新的行/句子。 因此,我有一个调用NLP API的函数: 我用ParDo为每个句子调用这个函数。我假设,下面的ParDo将自动为文本文件中的每一行调用NLP情感api(基本上我不必遍历文本文件中的每一行!) 但在执行数据流后,我得到了这个错误: T

  • 我检查了这个问题,在elasticsearch中查询DSL中必须和过滤器有什么区别?并阅读答案。 据我所知,必须和过滤器应该返回相同的结果。我说的对吗?但是当我把过滤查询改为必须时,我收到了更多的结果?我做错了什么? 我比较了过滤器,必须查询并得到不同的结果。

  • 我有以下简单的代码: 我得到了这个错误: "必须返回有效的React元素(或null)。您可能已返回未定义、数组或其他无效对象。"

  • 下面是我正在尝试使用firebase云功能所做的事情: -监听“用户”集合下的文档中的任何更改。 -更新“评论”和“发布”集合中相关文档中用户信息的副本。 因为我将需要在相关文档中进行查询并立即更新,所以我正在编写事务操作的代码。 这是我写的代码。它返回错误消息“Function returned undefined,expected Promise or value”。 我有点困惑,因为据我所知

  • 问题内容: 我想使用这样的Promise来调用Google Maps Geocoding API: 当我调用函数请求时,我发现我得到了一个Promise而不是一个值: 为什么不答应。然后在返回值之前执行?我如何从这个承诺而不是另一个承诺中获得价值? 问题答案: 如果您依赖承诺来返回数据,则必须从函数中返回承诺。 一旦调用堆栈中的1个函数异步,那么要继续线性执行,所有要调用它的函数也必须异步。(异步

  • 我试着像FOSRestBundleByExample/blob那样做。 我的行动: 不过,我有以下回应: 控制器必须返回一个响应(给定对象(FOS\RestBundle\View\View))。 我发现我可以在配置中将view\u response\u listener更改为true,但我有: 无法找到模板""。 有什么想法吗? 谢谢你,卡米尔