Javascript Firebase云的功能:";未处理的错误RangeError:超过最大调用堆栈大小;
我有一个使用firebase的云函数,在我从angular应用程序调用它后,我得到了上面提到的错误: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
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:/谢谢!我也会履行诺言的。