javascript - Firebase Promises 问题 - “超出最大调用堆栈大小”
问题描述
我有一个问题Callable Functions
。这是我的 Firebase 功能:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const request = require('request-promise');
admin.initializeApp(functions.config().firebase);
exports.phoneAuthRequest = functions.https.onCall((data, context) => {
// Message text passed from the client.
const text = data.text;
// Authentication / user information is automatically added to the request.
const uid = context.auth.uid;
const phone = context.auth.token.phone_number;
const url = "https://api.authy.com/protected/json/phones/verification/start?api_key=<key here>&via=sms&country_code=1&phone_number=" + phone;
const httpReq = {
uri: url,
method: 'POST',
json: true,
resolveWithFullResponse: true
};
return new Promise((resolve, reject) => {
request(httpReq).then((response) => {
// Twillio request returned with success
console.log("response: " + JSON.stringify(response));
return resolve(response);
}).catch(function(error) {
console.log("error: " + JSON.stringify(error));
return reject(error);
});
});
});
这是我的客户示例:
<html>
<head>
<script src="https://www.gstatic.com/firebasejs/5.4.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.4.2/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.4.2/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.4.2/firebase-functions.js"></script>
<script>
var config = { <firebase configuration in here> };
firebase.initializeApp(config);
function myTest() {
var display = document.getElementById('display');
display.innerHTML = "Started";
var auth = firebase.auth();
auth.signInWithEmailAndPassword(<username>,<password>).then(function(authResult) {
display.innerHTML = "Signed in";
var phoneAuthRequest = firebase.functions().httpsCallable('phoneAuthRequest');
phoneAuthRequest({'text': 'Test'}).then(function(result) {
display.innerHTML = JSON.stringify(result);
}).catch(function(error) {
display.innerHTML = JSON.stringify(error);
});
}).catch(function(error) {
display.innerHTML = "Login failure. Your email or password could not be validated. " + JSON.stringify(error);
});
}
</script>
</head>
<body>
<input type="submit" value="Test It" data-wait="Loading..." id="loginBtn" class="login-window-login-btn w-button" onclick="myTest();">
<div id="display"></div>
</body>
</html>
对此代码组合的测试表明,Firebase 函数“phoneAuthRequest”被调用,这反过来向 Twillio 发出请求,并且来自 Twillio 的响应在响应中正确返回,但控制台日志显示此错误:
Unhandled error RangeError: Maximum call stack size exceeded
at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13395:23)
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:13400:38
at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:4925:15
at baseForOwn (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:3010:24)
at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13399: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:13400:38
at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:4925:15
at baseForOwn (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:3010:24)
at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13399: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:13400:38
at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:4925:15
at baseForOwn (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:3010:24)
at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13399: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:13400:38
at /user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:4925:15
at baseForOwn (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:3010:24)
at Function.mapValues (/user_code/node_modules/firebase-functions/node_modules/lodash/lodash.js:13399:7)
at encode (/user_code/node_modules/firebase-functions/lib/providers/https.js:242:18)
当然,客户端的响应是:
{"code":"internal"}
当我阅读类似的帖子时,建议是序列化承诺,我不确定我是否完全理解如何去做,或者将异步调用(在这种情况下为请求)包装在新的承诺中,这正是我这里做了,还是不行。
如果您要回答这个问题,您能否通过显示代码示例具体说明建议的解决方案?
提前致谢...
解决方案
好的,我用大量的头撞墙解决了这个问题。这是代码:
exports.phoneAuthRequest = functions.https.onCall((data, context) => {
// Example of using context to obtain the user information about the calling user
const uid = context.auth.uid;
// Example of obtaining a paramter that was passed by the calling function
const phone = data.phone;
const e164 = "+1" + phone;
httpReq = ...
// Example of a return if you have not yet made a call to an asynchonous function.
return ({'status': 'success'});
// Here is an example of a nested set of asynchonous calls and how to return from them.
return admin.auth().updateUser(uid, {'phoneNumber': e164}).then(function(userRecord) {
// the Phone Number was updated
return request(httpReq).then((response) => {
var updates = {};
updates['/users/' + uid + "/centralVerified"] = false;
return database.ref().update(updates).then(function(rslt) {
return Promise.resolve({'status': 'success');
}).catch(function(error) {
return Promise.reject({'status': 'failed'});
});
}).catch(function(error) {
return Promise.reject({'status': 'failed'});
});
}).catch(function(error) {
return Promise.reject({'status': 'failed'});
});
});
请注意,上面有两种从可调用函数返回的不同方式。如果您没有进行任何异步调用,那么您可以简单地返回值,但如果您调用了异步函数,则必须返回一个 Promise。如果您在调用例程中查找 Reject 或 Resolve,则假定返回值是 Resolve。
我希望这对其他人有所帮助......祝你好运!
推荐阅读
- ios - Pop 和 Push 的导航在 SwiftUI 中不起作用?
- javascript - 如何在 JavaScript 中检查每一行的日期年份?
- excel - 选择多个单元格时评估错误:运行时错误“13”:类型不匹配
- babeljs - 如何在 babel AST 中的“尾随”注释之前添加新行?
- python - 这个 TensorFlow 程序在 Python 中的等效 R 代码是什么?
- ansible - 通过 cron 运行时,ansible playbook 挂起
- php - Trying to Get Data From Db using Form Under 10 Km
- css - align-items: end difference between Chrome and Firefox
- json - json 包含正确格式的字符串
- json - 具有 React 或 Angular 8 和 typescript 的集成 Rest API (json) BPMN