No se pueden leer archivos de alojamiento en una nube. Función

Mi función Firebase no está funcionando. Aquí está el registro:

introduzca la descripción de la imagen aquí

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 

No sé a qué se refiere “Excepción no detectada”.

El error “ENOENT: no existe tal archivo o directorio” podría ser un error de ruta de nodo. Aquí está mi estructura de directorio:

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

Y aquí está la línea que aparentemente está causando el error:

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

La línea usa Nodo para escribir un archivo. ¿Hay algo mal con el camino?

Aquí está la función completa:

 // 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.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/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 

Las primeras cuatro líneas cargan módulos de nodo. La función se llama “getWatsonToken”. Se activa cuando un usuario inicia sesión o, específicamente, cuando una línea de código en el proceso de inicio de sesión escribe la ID de autenticación del usuario en una ubicación en Firebase Realtime Database, y luego onUpdate activa la función. A continuación, los parámetros se definen para una solicitud HTTP y, a continuación, la solicitud HTTP se envía a IBM Watson. IBM devuelve un token para su servicio de voz a texto como el cuerpo de la respuesta HTTP. (Un console.log muestra el token, eso está funcionando.) Algunos JavaScript angular se envuelven alrededor del token. Por último, el archivo se escribe en una ubicación en un directorio. El último paso parece ser donde está el error.

Aquí hay otra vista de la estructura de mi directorio:

introduzca la descripción de la imagen aquí

¡Gracias por tu ayuda!

No puede usar una función de nube para leer y escribir archivos servidos por Firebase Hosting, incluso en el mismo proyecto.

Cuando utiliza la CLI de Firebase para implementar, cada producto se implementa por separado. Por lo tanto, todo su contenido estático para Firebase Hosting en su carpeta public se envía a un lugar y todo su código de Funciones de la nube se envía a otro lugar. Después de eso, no comparten nada en común.

Puede leer los archivos en la carpeta de functions después de la implementación. Pero obviamente, estos no tienen nada que ver con el Hosting después de la implementación.

Recomiendo encarecidamente que no intente escribir archivos en una función de nube, especialmente para su caso de uso. Lo que está tratando de hacer se sirve mejor escribiendo datos persistentes en Realtime Database, Firestre o incluso Cloud Storage. Los archivos de disco en Cloud Functions no son persistentes, y puede tener múltiples instancias de servidores que ejecutan funciones que no se conocen entre sí.

¡Gracias Doug! Aquí está mi función Firebase de trabajo:

 // 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.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/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 

Esto escribe el token en mi base de datos en tiempo real de Firebase. Mi código de controlador es:

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

Este código hace referencia a la ubicación en Firebase Realtime Database, luego escucha los cambios en el valor, luego forEach lee el valor y pone el valor en $scope para que lo utilicen las funciones del controlador.

Lo haré más rápido eliminando la promesa y console.log en la función.