I'm having an issue with Callable Functions
. Here's my Firebase function:
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);
});
});
});
And here is my client example:
<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>
A test of this code combination shows that the Firebase function 'phoneAuthRequest' gets called, which in turn makes the request to Twillio, and the response from Twillio is returned correctly in response, but the Console Logs show this error:
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)
And of course, the response back at the client is:
{"code":"internal"}
As I read similar posts, the advice was to serialize the promises, which I'm not sure I totally understand how to do, or, to wrap the async call (request in this case) inside of a new promise, which is exactly what I have done here, and it still doesn't work.
If you are going to answer this question, can you please be specific about the proposed solution by showing a code example?
Thanks in advance...