【问题标题】:Firebase transaction triggers function error?Firebase 事务触发函数错误?
【发布时间】:2019-02-22 16:55:09
【问题描述】:

已经花了好几个小时试图弄清楚以下内容,希望有人能指出我。

简而言之,发生了什么:我有一个 firebase 函数,它基本上更新事务中的数据库值。但是如果我使用事务,函数总是会因为这个错误而失败:

Unhandled error RangeError: Maximum call stack size exceeded
    at Function.isNull

即使事务正确更新了数据库中的值。

我试图调试它并删除我可以删除的任何内容。因此,每当我删除事务并使用 update() 时,函数都会按预期完成,代码为 200。

只要我把事务放回去,函数就会失败,并显示以下堆栈跟踪:

Unhandled error RangeError: Maximum call stack size exceeded
    at Function.isNull (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:11950:20)
    at encode (/user_code/node_modules/firebase-functions/lib/providers/https.js:217:11)
    at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13402:38
    at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:4911:15
    at baseForOwn (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:2996:24)
    at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13401:7)
    at encode (/user_code/node_modules/firebase-functions/lib/providers/https.js:242:18)
    at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13402:38
    at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:4911:15
    at baseForOwn (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:2996:24)
    at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13401:7)

我得到的另一个类似的堆栈跟踪:

Unhandled error RangeError: Maximum call stack size exceeded
    at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13402:38
    at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:4911:15
    at baseForOwn (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:2996:24)
    at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13401:7)
    at encode (/user_code/node_modules/firebase-functions/lib/providers/https.js:242:18)
    at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13402:38
    at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:4911:15
    at baseForOwn (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:2996:24)
    at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13401:7)
    at encode (/user_code/node_modules/firebase-functions/lib/providers/https.js:242:18)

函数如下:

index.js:

    const statsModule = require("./stats")

    exports.myMethod9 = functions.https.onCall((data, context) => {
        console.log("updateStatsMessagesChangedFeedbackHttp: data = ", data)
        return statsModule.updateStatsMessagesChangedFeedbackHttp(data, context, admin);
    });

stats.js

exports.updateStatsMessagesChangedFeedbackHttp = function (data, context, admin) {
    var userId = "sdfsdf";
    var feedback = data.feedback;
    console.log("updateStatsMessagesChangedFeedbackHttp: userId = ", userId)
    return exports.updateStatsMessagesChangedFeedback(userId, feedback, admin);
}

exports.updateStatsMessagesChangedFeedback = function (userId, feedback, admin) {
    console.log("updateStatsMessagesChangedFeedback: feedback = ", feedback, ", userId = ", userId);

    var root = admin.database().ref().root;
    var path = constModule.statsUpdatedMessagesFeedbackPath + "/" + feedback;
    var statsRef = root.child(path);
    return statsRef.transaction(function (stats) {
        if(!stats) {
            stats = {votedUsers:{}, count: 0};
        }
        stats.votedUsers[userId] = true;
        console.log("updateStatsMessagesChangedFeedback: stats = ", stats)
        return stats;
    }, function (error, committed, snapshot) {
        //nothing wrong here - error is always null, committed - true

        var snapVal = snapshot ? snapshot.val() : null;
        console.log("error = ", error, ", committed = ", committed, ", data = ", snapVal);
        if (error) {
            // The fetch succeeded, but the update failed.
            console.error("updateStatsMessagesChangedFeedback: The fetch succeeded, but the update failed: ", error);
        } else {
            console.log("updateStatsMessagesChangedFeedback: all ok: data = ", snapVal);
        }
    })
    .catch(function (error) {
        //this is never called - all good here as well
        console.error("updateStatsMessagesChangedFeedback: error = ", error)
    });
}

我这样从客户端 web sdk 调用它:

var call = firebase.functions().httpsCallable('myMethod9');dFeedbackHttp
call({feedback: "some data"}).then(function (result) {...})

catch 和事务回调都没有显示任何错误。虽然只有当我使用事务时功能仍然失败。

(点击图片放大)

有什么想法吗?

【问题讨论】:

    标签: firebase google-cloud-functions


    【解决方案1】:

    在与支持人员讨论后(顺便说一句,非常有帮助的人!)这里是解决方案:

    在交易的情况下需要从函数中返回一个值:

     exports.myMethod9 = functions.https.onCall((data, context) => {
            console.log("updateStatsMessagesChangedFeedbackHttp: data = ", data)
            return statsModule.updateStatsMessagesChangedFeedbackHttp(data, context, admin);
        }).then(function(){
            return {}
        });
    

    我不知道为什么返回一个值在这里有任何区别,例如 update() 返回 void 仍然使函数完成,代码为 200。

    等待进一步的 cmets 形成支持,同时如果有人对此有任何信息,请随时分享。

    【讨论】:

      猜你喜欢
      • 2014-05-23
      • 1970-01-01
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      • 1970-01-01
      • 2018-05-17
      • 2019-10-10
      • 1970-01-01
      相关资源
      最近更新 更多