1

I'm sorry, but I've watched all seven of Jennifer Person's videos, read the documentation, and worked through the tutorials but I still don't see how to write my function. I'm trying to write a function that gets an IBM Watson Speech-to-text token, which is obtained with this CURL script:

curl -X GET --user username:password --output token
"https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api"

I.e., send an HTTP GET request to the URL, provide my username and password, and then write the output to the file /javascript/services/token.

This is my guess as to the function. An authentication trigger wraps a Nodejs HTTP GET request, and a NodeJs file save fs.writefile.

const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.getWatsonToken = functions.auth.user().onCreate(event => { // authentication trigger

  var https = require('https');  // Nodejs http.request

  var options = {
    host: 'stream.watsonplatform.net',
    path: '/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api',
    username: groucho,
    password: swordfish
  };

  callback = function(response) {
    response.on('end', function () {
      console.log(response);
      fs.writeFile("/javascript/services/token", response);
    });
  }

  http.request(options, callback).end();

});
Let Me Tink About It
  • 11,866
  • 13
  • 72
  • 169
Thomas David Kehoe
  • 7,232
  • 7
  • 44
  • 73
  • Regarding the missing tag--because Cloud Functions for Firebase is a wrapper around Google Cloud Functions, that tag is used. See https://stackoverflow.com/a/42859932/4815718 – Bob Snyder Sep 08 '17 at 17:53
  • Did you check billing is enabled for your Firebase project? Because you cannot call external url. It's limitation of free account – nagabandaru Sep 08 '17 at 18:27
  • You can't just write to arbitrary files on a Cloud Functions instance. You can write to /tmp. But that isn't guaranteed to stick around. Why do you need data in a file? What's the end game? – Doug Stevenson Sep 08 '17 at 20:15
  • Cloud Functions are meant to be state-less, so store that file in Firebase Storage, or write it to the database, don't leave on the file system as it won't stay stored. – sketchthat Sep 09 '17 at 02:01

1 Answers1

2

This function works:

// Node modules
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const request = require('request'); // node module to send HTTP requests
const fs = require('fs');

admin.initializeApp(functions.config().firebase);

exports.getWatsonToken = functions.database.ref('userLoginEvent').onUpdate(event => { // authentication trigger when user logs in

  var username = 'groucho',
      password = 'swordfish',
      url = 'https://' + username + ':' + password + '@stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api';

  request({url: url}, function (error, response, body) {

    var tokenService = "app.value('watsonToken','" + body + "');";

    fs.writeFile('../public/javascript/services/watsonTokenValue.js', tokenService, (err) => {
      if (err) throw err;
        console.log('The file has been saved!');
    }); // close fs.writeFile

  }); // close request

}); // close getWatsonToken

In the controller:

 firebase.auth().onAuthStateChanged(function(user) { // this runs on login
    if (user) { // user is signed in
      console.log("User signed in!");
      $scope.authData = user;
      firebase.database().ref('userLoginEvent').update({'user': user.uid}); // update Firebase database to trigger Cloud Function to get a new IBM Watson token
    } // end if user is signed in
    else { // User is signed out
      console.log("User signed out.");
    }
  }); // end onAuthStateChanged

Walking through the Cloud Function, it injects four Node modules, including request for sending HTTP requests, and fs for writing the results to a file. Then the trigger is set for an update to a location userLoginEvent in the Firebase database (which I created from the console). Next, the HTTP request goes out. The response (the token) is called body.app.value('watsonToken','" + body + "'); is an Angular value service to wrap the token. Then fs writes all this to a location in my project.

In the AngularJS controller, onAuthStateChanged triggers when a user logins in. The user.uid is then updated to the location userLoginEvent in the Firebase database, and the Cloud Function triggers, the HTTP request goes out, and the response is written to an Angular service.

Let Me Tink About It
  • 11,866
  • 13
  • 72
  • 169
Thomas David Kehoe
  • 7,232
  • 7
  • 44
  • 73
  • For your solution to work, I believe you have to be running something other than [the Spark (free) plan](https://firebase.google.com/pricing/). Can you please please confirm you are using either Flame or Blaze (paid) plan? Also, I'm curious which you chose. – Let Me Tink About It Dec 02 '17 at 20:33