Javascript Firebase云的功能:";未处理的错误RangeError:超过最大调用堆栈大小;

Javascript Firebase云的功能:";未处理的错误RangeError:超过最大调用堆栈大小;,javascript,firebase,firebase-realtime-database,google-cloud-functions,Javascript,Firebase,Firebase Realtime Database,Google Cloud Functions,我有一个使用firebase的云函数,在我从angular应用程序调用它后,我得到了上面提到的错误: Unhandled error RangeError: Maximum call stack size exceeded at baseKeys (/workspace/node_modules/lodash/lodash.js:3483:12) at keys (/workspace/node_modules/lodash/lodash.js:13333:60) at

我有一个使用firebase的云函数,在我从angular应用程序调用它后,我得到了上面提到的错误:

Unhandled error RangeError: Maximum call stack size exceeded
    at baseKeys (/workspace/node_modules/lodash/lodash.js:3483:12)
    at keys (/workspace/node_modules/lodash/lodash.js:13333:60)
    at /workspace/node_modules/lodash/lodash.js:4920:21
    at baseForOwn (/workspace/node_modules/lodash/lodash.js:2990:24)
    at Function.mapValues (/workspace/node_modules/lodash/lodash.js:13426:7)
    at encode (/workspace/node_modules/firebase-functions/lib/providers/https.js:184:18)
    at /workspace/node_modules/lodash/lodash.js:13427:38
    at /workspace/node_modules/lodash/lodash.js:4925:15
    at baseForOwn (/workspace/node_modules/lodash/lodash.js:2990:24)
    at Function.mapValues (/workspace/node_modules/lodash/lodash.js:13426:7
我搜索了堆栈以找到解决方案,但在大多数情况下都存在序列化问题,我相信这里不会出现这种情况

以下是我的功能:

    exports.createCase = functions.region('europe-west2').https.onCall((data, context) => {
    console.log("creating new case");

    if (!context.auth) {
        throw new functions.https.HttpsError('failed-precondition', 'This function must be called ' +
            'while authenticated.');
    }

    const caseName = data.caseName;
    // Authentication / user information is automatically added to the request.
    const uid = context.auth.uid;
    const name = context.auth.token.name || null;
    const picture = context.auth.token.picture || null;
    const email = context.auth.token.email || null;

    console.log("caseName=" + caseName + " uid=" + uid + " name=" + name + " picture=" + 
      picture + " email=" + email);

    var operationResult = new Promise ((resolve, reject) => {
      var accessData : any = {};      
      var accessId = admin.database().ref('/access/').push();
      var operationId = admin.database().ref('/operationslog/' + accessId.key + '/').push();
      console.log("accessId created=" + accessId + ' ||  ' + accessId.key + ' operations id=' +
       operationId + ' || ' + operationId.key);
            
      let now: number = Date.now();
      accessData[`/access/` + accessId.key] = new Access(caseName, uid, email);
      accessData[`/operationslog/` + accessId.key + `/` + operationId.key] = {
        date: now,
        performedByUser: uid,
        performedByMail: email,
        performedByImg: picture,
        performedBySystem: false,
        operationType: 'CREATE',
        order: (REVERSE_ORDER_MAX - now),
        details: {creator: uid, name: caseName}
      };
      console.log('commiting data');
      admin.database().ref().update(accessData).then( (value: void) => {
          console.log("returning ok result");
          resolve({
            status: "Ok",
            accessId: accessId,
            description: 'Case created'
          });
        }, err => {
          console.log("Error while trying to create case: " + err);
          reject("CASE NOT CREATED");
        }
      ).catch(exception => {
          console.log("Error while trying to create case: " + exception);
          reject("CASE NOT CREATED");
        }
      );
    }
    );

    return operationResult;
  });
以及Angular应用程序的呼叫:

let createCaseCall = functions.httpsCallable('createCase');
createCaseCall({caseName: value.caseName}).then(result => {
      // Read result of the Cloud Function.
      console.log("got result: " + result);
      if (result.data.status == 'Ok') {
        this.showSuccessMessage('Case created.');
      }
    }).catch(err => {
      console.log("Error while calling cloud functions: " + err);
      this.showErrorMessage('Error while creating the case.');
    });

现在,重要的信息是,调用此函数时会创建firebase实时数据库中的数据,并且控制台日志确实包含“返回确定结果”行…

这仍然是一个序列化问题

以下是您试图发送回客户端的内容:

          resolve({
            status: "Ok",
            accessId: accessId,
            description: 'Case created'
          });
accessId
是推送操作的结果:

  var accessId = admin.database().ref('/access/').push();
这意味着它是一个DatabaseReference对象,其中包含无法序列化的循环引用。它不像字符串那样是一种简单的数据类型

你需要更仔细地考虑你想要什么,确切地说,你想要发送回客户端应用程序。可能您想发回由
push()
创建的子密钥的名称或路径


另外,您可能需要删除整个
newpromise()
东西,因为这是一个反模式。如果您可以使用所有其他数据库操作的承诺,则无需创建新的承诺。

是的,这应该是accessId.key:/谢谢!我也会履行诺言的。