最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Can't read hosting files in a cloud Function - Stack Overflow

programmeradmin0浏览0评论

My Firebase function isn't working. Here's the log:

11:01:03.932 AM warning getWatsonToken Error: ENOENT: no such file or directory, open '../public/javascript/services/watsonTokenValue.js'
    at Error (native)

11:01:03.831 AM warning getWatsonToken Uncaught exception

11:01:03.233 AM info    getWatsonToken 5YGY3R%2FBP0zelDOaob9PnxMWDj...

11:01:00.139 AM outlined_flag getWatsonToken Function execution took 804 ms, finished with status: 'ok'

11:00:59.834 AM info    getWatsonToken Executing function!

11:00:59.335 AM outlined_flag getWatsonToken Function execution started

I don't know what "Uncaught exception" is referring to.

The "ENOENT: no such file or directory" error might be a Node path mistake. Here's my directory structure:

── functions
    ├── index.js // this is my function
── public
    ├── javascript
    │   ├── services
    │   │   ├── watsonTokenValue.js // this is the file I want to write to

And here's the line that's apparently causing the error:

fs.writeFile('../public/javascript/services/watsonTokenValue.js', tokenService, (err) => {

The line uses Node to write a file. Is there something wrong with the path?

Here's the full function:

// 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
  console.log("Executing function!");
  var username = '56ae6a1e7854',
  password = 'swordfish',
  url = 'https://' + username + ':' + password + '@stream.watsonplatform/authorization/api/v1/token?url=';

  request({url: url}, function (error, response, body) {
    console.log(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
return 0; // prevents an error message "Function returned undefined, expected Promise or value"
}); // close getWatsonToken

The first four lines load Node modules. The function is called "getWatsonToken." It triggers when a user logs in, or, specifically, when a line of code in the login process writes the user's Auth ID to a location in Firebase Realtime Database, and then onUpdate triggers the function. Next, parameters are defined for an HTTP request, and then the HTTP request is sent to IBM Watson. IBM returns a token for its speech-to-text service as the body of the HTTP response. (A console.log shows the token, that's working.) Some Angular JavaScript then is wrapped around the token. Lastly, the file is written to a location in a directory. The last step seems to be where the error is.

Here's another view of my directory structure:

Thanks for your help!

My Firebase function isn't working. Here's the log:

11:01:03.932 AM warning getWatsonToken Error: ENOENT: no such file or directory, open '../public/javascript/services/watsonTokenValue.js'
    at Error (native)

11:01:03.831 AM warning getWatsonToken Uncaught exception

11:01:03.233 AM info    getWatsonToken 5YGY3R%2FBP0zelDOaob9PnxMWDj...

11:01:00.139 AM outlined_flag getWatsonToken Function execution took 804 ms, finished with status: 'ok'

11:00:59.834 AM info    getWatsonToken Executing function!

11:00:59.335 AM outlined_flag getWatsonToken Function execution started

I don't know what "Uncaught exception" is referring to.

The "ENOENT: no such file or directory" error might be a Node path mistake. Here's my directory structure:

── functions
    ├── index.js // this is my function
── public
    ├── javascript
    │   ├── services
    │   │   ├── watsonTokenValue.js // this is the file I want to write to

And here's the line that's apparently causing the error:

fs.writeFile('../public/javascript/services/watsonTokenValue.js', tokenService, (err) => {

The line uses Node to write a file. Is there something wrong with the path?

Here's the full function:

// 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
  console.log("Executing function!");
  var username = '56ae6a1e7854',
  password = 'swordfish',
  url = 'https://' + username + ':' + password + '@stream.watsonplatform/authorization/api/v1/token?url=https://stream.watsonplatform/speech-to-text/api';

  request({url: url}, function (error, response, body) {
    console.log(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
return 0; // prevents an error message "Function returned undefined, expected Promise or value"
}); // close getWatsonToken

The first four lines load Node modules. The function is called "getWatsonToken." It triggers when a user logs in, or, specifically, when a line of code in the login process writes the user's Auth ID to a location in Firebase Realtime Database, and then onUpdate triggers the function. Next, parameters are defined for an HTTP request, and then the HTTP request is sent to IBM Watson. IBM returns a token for its speech-to-text service as the body of the HTTP response. (A console.log shows the token, that's working.) Some Angular JavaScript then is wrapped around the token. Lastly, the file is written to a location in a directory. The last step seems to be where the error is.

Here's another view of my directory structure:

Thanks for your help!

Share Improve this question edited Jan 23, 2018 at 20:27 Thomas David Kehoe asked Jan 23, 2018 at 18:33 Thomas David KehoeThomas David Kehoe 11k18 gold badges75 silver badges122 bronze badges 2
  • 2 Do not post images of code or errors! Images and screenshots can be a nice addition to a post, but please make sure the post is still clear and useful without them. If you post images of code or error messages make sure you also copy and paste or type the actual code/message into the post directly. – Rob Commented Jan 23, 2018 at 18:38
  • Thanks, I just edited in the error text. – Thomas David Kehoe Commented Jan 23, 2018 at 20:28
Add a ment  | 

2 Answers 2

Reset to default 7

You can't use a Cloud Function to read and write files served by Firebase Hosting, even in the same project.

When you use the Firebase CLI to deploy, each product is deployed separately. So, all your static content for Firebase Hosting in your public folder gets sent to one place, and all your Cloud Functions code gets sent to another place. After that, they share nothing in mon.

You can read files under the functions folder after deployment. But obviously, those have nothing to do with Hosting after deployment.

I strongly remend against trying to write files in a Cloud Function, especially for your use case. What you're trying to do is better served by writing persistent data to Realtime Database, Firestore, or even Cloud Storage. Disk files in Cloud Functions are not persistent, and you may have multiple instances of servers running functions that know nothing of each other.

Thanks, Doug! Here's my working Firebase function:

// 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 = '56ae6a1e7854',
  password = 'swordfish',
  url = 'https://' + username + ':' + password + '@stream.watsonplatform/authorization/api/v1/token?url=https://stream.watsonplatform/speech-to-text/api';
  request({url: url}, function (error, response, body) {
    admin.database().ref('IBMWatsonToken').set({'token': body})
    .then(function()  {
      console.log("Token saved!");
    }); // close promise
  }); // close request
return 0; // prevents an error message "Function returned undefined, expected Promise or value"
}); // close getWatsonToken

This writes the token to my Firebase Realtime Database. My controller code is:

firebase.database().ref('IBMWatsonToken').on('value', function(snapshot) {
    snapshot.forEach(function(childSnapshot) {
    $scope.watsonToken = childSnapshot.val();
    });
  });

This code references the location in Firebase Realtime Database, then on listens for changes in the value, then the forEach reads the value and puts the value on the $scope for controller functions to use.

I'll make it faster by removing the promise and console.log in the function.

发布评论

评论列表(0)

  1. 暂无评论