【问题标题】:Why is my firebase transaction expired or no longer valid?为什么我的 Firebase 交易已过期或不再有效?
【发布时间】:2019-07-05 09:04:59
【问题描述】:

我正在寻求有关如何在我的 firebase/angular 6 应用程序中使用事务的帮助。

我有这个:

    let transactionResult;
    try {
        transactionResult = await db.runTransaction(trans => {
            console.log('running transaction');
            const result = trans.commit();
            console.log('result =', result);
            return result;
        });
    } catch (err) {
        console.log('catching error; err =', err);
    }
    console.log('transactionResult =', transactionResult);

我得到这个输出:

running transaction
info: result = Promise { <pending> }
info: catching error; err = { Error: 10 ABORTED: The referenced transaction has expired or is no longer valid.
at Object.exports.createStatusError (/Users/gibranshah/repos/EVABlockchain/functions/node_modules/firebase-admin/node_modules/grpc/src/common.js:87:15)
at Object.onReceiveStatus (/Users/gibranshah/repos/EVABlockchain/functions/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:1188:28)
at InterceptingListener._callNext (/Users/gibranshah/repos/EVABlockchain/functions/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:564:42)
at InterceptingListener.onReceiveStatus (/Users/gibranshah/repos/EVABlockchain/functions/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:614:8)
at callback (/Users/gibranshah/repos/EVABlockchain/functions/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:841:24)
code: 10,
metadata: Metadata { _internal_repr: {} },
details: 'The referenced transaction has expired or is no longer valid.',
note: 'Exception occurred in retry method that was not classified as transient' }

我不熟悉事务的工作原理,所以我不知道“引用的事务已过期或不再有效”是什么意思。或“未分类为瞬态的重试方法中发生异常”。 我正在尝试运行尽可能简单的事务。所以我运行 commit() 并返回结果。而已。我认为这很简单。

如果我在事务中不做任何事情如下:

        transactionResult = await db.runTransaction(trans => {
            console.log('running transaction');
        });

我明白了:

info: running transaction
info: catching error; err = Error: You must return a Promise in your transaction()-callback.
at transaction.begin.then (/Users/gibranshah/repos/EVABlockchain/functions/node_modules/firebase-admin/node_modules/@google-cloud/firestore/build/src/index.js:494:32)
at <anonymous>

如果我返回一个已解决的承诺,如下所示:

        transactionResult = await db.runTransaction(trans => {
            console.log('running transaction');
            return Promise.resolve();
        });

我明白了:

info: running transaction
info: running transaction
info: running transaction
info: running transaction
info: running transaction
info: catching error; err = TypeError: Cannot read property 'seconds' of null
at Function.fromProto (/Users/gibranshah/repos/EVABlockchain/functions/node_modules/firebase-admin/node_modules/@google-cloud/firestore/build/src/timestamp.js:91:47)
at _firestore.request.then.resp (/Users/gibranshah/repos/EVABlockchain/functions/node_modules/firebase-admin/node_modules/@google-cloud/firestore/build/src/write-batch.js:472:42)
at <anonymous>

它似乎反复运行事务,直到它尝试从空对象中读取“秒”。

我能写出的最简单的交易是什么?

【问题讨论】:

  • 如果您打算在该事务期间编写文档(您没有这样做),您只需要一个事务。你确定你需要在这里交易吗? (您返回的承诺通常是文档更新的结果。)

标签: angular firebase transactions google-cloud-firestore


【解决方案1】:

事实证明,您确实必须至少进行一次读取和一次写入。这样做:

    transactionResult = await db.runTransaction(trans => {
        console.log('running transaction');
        const ref = db.collection(colPath).doc(docPath);
        return trans.get(ref).then(doc => {
            const d = doc.data();
            // update data
            return trans.set(ref, d);
        });
    });

... 成功了。我正在返回集合的结果,这似乎满足了事务(即它提交并且不重复并且没有错误)。

【讨论】:

    【解决方案2】:

    您应该在开头添加 return

     return db.runTransaction(trans => {
                console.log('running transaction');
            });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-30
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      • 2011-08-20
      • 1970-01-01
      • 1970-01-01
      • 2016-12-07
      相关资源
      最近更新 更多