2

I've been trying to get authy-client to run with Firebase Cloud Functions but I keep running into a ValidationFailedError. I've been testing the examples the author supplied at https://www.npmjs.com/package/authy-client with no luck.

For my Firebase function, I've been trying this:

const Client = require('authy-client').Client;
const client = new Client({ key: 'my API key here' });

exports.sendVerificationCode = functions.database.ref('users/{userId}/verify/status')
.onCreate(event => {
  const sender = client.registerUser({
    countryCode: 'US',
    email: 'test@tester.com',
    phone: '4035555555'
  }).then( response => {
    return response.user.id;
  }).then( authyId => {
    return client.requestSms({ authyId: authyId });
  }).then( response => {
    console.log(`SMS requested to ${response.cellphone}`);
    throw Promise;
  });

  return Promise.all([sender]);
});

But I get this error:

ValidationFailedError: Validation Failed
    at validate (/user_code/node_modules/authy-client/dist/src/validator.js:74:11)
    at _bluebird2.default.try (/user_code/node_modules/authy-client/dist/src/client.js:632:31)
    at tryCatcher (/user_code/node_modules/authy-client/node_modules/bluebird/js/release/util.js:16:23)
    at Function.Promise.attempt.Promise.try (/user_code/node_modules/authy-client/node_modules/bluebird/js/release/method.js:39:29)
    at Client.registerUser (/user_code/node_modules/authy-client/dist/src/client.js:617:34)
    at exports.sendVerificationCode.functions.database.ref.onCreate.event (/user_code/index.js:24:25)
    at Object.<anonymous> (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:59:27)
    at next (native)
    at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
    at __awaiter (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
    at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:53:36)
    at /var/tmp/worker/worker.js:695:26
    at process._tickDomainCallback (internal/process/next_tick.js:135:7)

I am new to Firebase' cloud functions so I may be overlooking something obvious but from what I've read, then() statements and the function itself needs to return/throw a Promise so I hacked that together.

I've also made sure that authy-client is included in the dependencies in the package.json file.

I originally signed up for the Twilio trial which gave me an option to create an application with Authy. Needing to be sure, I also signed in to Authy to check if the API key is the same, and they are. So I don't think the validation error is due to the API key.

Any help would be appreciated. Thank you.

ReyAnthonyRenacia
  • 17,219
  • 5
  • 37
  • 56
Freakium
  • 31
  • 4

3 Answers3

1

Thank you all for your answers. I was finally able to figure out a solution. It had nothing to do with the code, well throw Promise was a mistake but it was apparently a problem with DNS resolutions that was resolved when I set up billing on Firebase.

As for my final code, as I originally wanted to use authy-client for phone verification, it looks something like this:

exports.sendVerificationCode = functions.database.ref('users/{userId}/verify')
.onCreate(event => {
  const status = event.data.child('status').val();
  const phoneNum = event.data.child('phone').val();
  const countryCode = event.data.child('countryCode').val();
  var method;

  if(status === 'pendingSMS')
    method = 'sms';
  else
    method = 'call';

  // send code to phone
  const sender = authy.startPhoneVerification({ countryCode: countryCode, phone: phoneNum, via: method })
  .then( response => {
    return response;
  }).catch( error => {
    throw error;
  });

  return Promise.all([sender]);
});
Freakium
  • 31
  • 4
0

throw Promise doesn't really mean anything. If you want to capture problems that can occur anywhere in your sequence of promises, you should have a catch section. The general form is this:

return someAsyncFunction()
    .then(...)
    .then(...)
    .catch(error => { console.error(error) })

That doesn't necessarily fix your error, though. That could be coming from the API you called.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
0

Twilio developer evangelist here.

Doug is right about throw Promise, that will definitely need to be changed.

However, the error seems to be coming before that and from the API. Specifically, the stack trace tells us:

    at Client.registerUser (/user_code/node_modules/authy-client/dist/src/client.js:617:34)

So the issue is within the registerUser function. The best thing to do is try to expose more of the error that is being generated from the API. That should give you the information you need.

Something like this should help:

const Client = require('authy-client').Client;
const client = new Client({ key: 'my API key here' });

exports.sendVerificationCode = functions.database.ref('users/{userId}/verify/status')
.onCreate(event => {
  const sender = client.registerUser({
    countryCode: 'US',
    email: 'test@tester.com',
    phone: '4035555555'
  }).then( response => {
    return response.user.id;
  }).then( authyId => {
    return client.requestSms({ authyId: authyId });
  }).then( response => {
    console.log(`SMS requested to ${response.cellphone}`);
  }).catch( error => {
    console.error(error.code);
    console.error(error.message);
    throw error;
  });    
});

Let me know if that helps at all.

philnash
  • 70,667
  • 10
  • 60
  • 88
  • Thank you for your help. I was finally able to figure out a solution and the problem was on my end. DNS resolutions from non-Google resources are apparently not allowed until billing is set up on Firebase. – Freakium Feb 07 '18 at 22:47