I would like to return the response of this callback

175 Views Asked by At

Small issue in debugging this. I have this piece of code which calls the cloud function.

HttpsCallable callable =
        FirebaseFunctions.instanceFor(region: 'us-central1')
            .httpsCallable("sendSMStoPhoneNumbers");
    final resp = await callable.call({
      "phoneNumbers": ["+40744440439"]
    });

and this cloud function

const functions = require("firebase-functions");
const initMB = require("messagebird");

/* eslint-disable-next-line max-len */
exports.sendSMStoPhoneNumbers = functions.https.onCall(async (data, context) => {
  const phoneNumbers = data.phoneNumbers;
  functions.logger.info("Hello logs!", {structuredData: true});
  const messagebird = initMB("CVxxxxxxxxxxxxxxxx");
  const params = {
    "originator": "TestMessage",
    "recipients": phoneNumbers,
    "body": "This is a test message",
  };
  /* eslint-disable-next-line max-len */
  messagebird.messages.create(params, function(err, response) {
    functions.logger.info(response, {structuredData: true});
    return response;
  });
   functions.logger.info("finish", {structuredData: true});
});

Right now happens that front end receives null all the time, it does not wait for messagebird's "create" method to finish. I tried to await it, same thing, I tried to put return in front of it, nothing changed. Console prints "finish" before the response of course.

create method defined inside module:

       * Send a text message
       *
       * @param {Object} params
       * @param {Function} callback
       * @return {void}
       */
      create: function (params, callback) {
        if (params.recipients instanceof Array) {
          params.recipients = params.recipients.join(',');
        }

        httpRequest({ method: 'POST', path: '/messages', params: params }, callback);
      }

  function httpRequest(requestParams, callback) {
var options = {};
var complete = false;
var body = null;
var request;

if (typeof requestParams === 'function') {
  callback = requestParams;
  requestParams = null;
}

/**
 * doCallback prevents multiple callback
 * calls emitted by node's http module
 *
 * @param {Error} err
 * @param {Mixed} res
 * @return {Void}
 */
function doCallback(err, res) {
  if (!complete) {
    complete = true;
    callback(err, res || null);
  }
}

function getUserAgent() {
  if (IS_FIREBASE_PLUGIN_ENABLED) {
    return 'MessageBird/ApiClient/FirebasePlugin';
  }
  return 'MessageBird/ApiClient/' + pkg.version + ' Node.js/' + process.versions.node;
}

// build request
options = {
  hostname: requestParams.hostname || 'rest.messagebird.com',
  path: requestParams.path,
  method: requestParams.method,
  headers: {
    'Authorization': 'AccessKey ' + config.accessKey,
    'User-Agent': getUserAgent()
  }
};

if (options.method === 'POST' || options.method === 'PUT' || options.method === 'PATCH') {
  body = JSON.stringify(requestParams.params);
  options.headers['Content-Type'] = 'application/json';
  options.headers['Content-Length'] = Buffer.byteLength(body, 'utf8');
} else {
  options.path += requestParams.params ? '?' + querystring.stringify(requestParams.params) : '';
}

// you can override any headers you like
options.headers = extend(options.headers || {}, requestParams.headers || {});

request = http.request(options);

// set timeout
request.on('socket', function (socket) {
  socket.setTimeout(parseInt(config.timeout, 10));
  socket.on('timeout', function () {
    request.abort();
  });
});

// process client error
request.on('error', function (e) {
  var error = new Error('request failed: ' + e.message);

  if (error.message === 'ECONNRESET') {
    error = new Error('request timeout');
  }

  error.error = e;
  doCallback(error);
});

// process response
request.on('response', function (response) {
  var data = [];
  var size = 0;
  var error = null;

  response.on('data', function (ch) {
    data.push(ch);
    size += ch.length;
  });

  response.on('close', function () {
    doCallback(new Error('request closed'));
  });

  response.on('end', function () {
    data = Buffer.concat(data, size)
      .toString()
      .trim();

    if (response.statusCode === 204) {
      doCallback(null, true);
      return;
    }

    try {
      let contentDisposition = response.headers['content-disposition'];

      // check if response data is downloadable so it can't be parsed to JSON
      if (contentDisposition && contentDisposition.includes('attachment')) {
        doCallback(error, data);
        return;
      }

      data = JSON.parse(data);
      if (data.errors) {
        let clientErrors = data.errors.map(function (e) {
          return e.description + ' (code: ' + e.code + (e.parameter ? ', parameter: ' + e.parameter : '') + ')';
        });

        error = new Error('api error(s): ' + clientErrors.join(', '));
        error.statusCode = response.statusCode;
        error.errors = data.errors;
        data = null;
      }
    } catch (e) {
      error = new Error('response failed');
      error.statusCode = response.statusCode;
      error.error = e;
      data = null;
    }

    doCallback(error, data);
  });
});

// do request
request.end(body);}
1

There are 1 best solutions below

0
On

Backed up by Frank's answer for another question, finally I solved my problem.

Node/Firebase onCall asynchronous function return

return new Promise((resolve, reject) => {
    messagebird.messages.create(params, function(err, response) {
      if (err) {
        reject(err);
      }
      resolve(response);
    });
  });