Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 无法使用https callable从云函数返回数据_Javascript_Node.js_Firebase_Google Cloud Functions_Angularfire2 - Fatal编程技术网

Javascript 无法使用https callable从云函数返回数据

Javascript 无法使用https callable从云函数返回数据,javascript,node.js,firebase,google-cloud-functions,angularfire2,Javascript,Node.js,Firebase,Google Cloud Functions,Angularfire2,我正在从Angular应用程序调用以下云函数,但返回的值始终为null,即使云函数正确地记录了结果。我不确定我做错了什么 我的角度代码如下: const data = {test: testToProcess}; const process = this.fns.httpsCallable("gprocess"); // fns is Angular Fire Functions process(data) .toPromise() // since Angular Fi

我正在从Angular应用程序调用以下云函数,但返回的值始终为null,即使云函数正确地记录了结果。我不确定我做错了什么

我的角度代码如下:

const data = {test: testToProcess};
const process = this.fns.httpsCallable("gprocess"); // fns is Angular Fire Functions
process(data)
  .toPromise() // since Angular Fire function returns an observable, Iam converting to a promise
  .then(
    (result) => {
      console.log("function called: " + JSON.stringify(result));
    },
    (err) => {
      console.log("Function call error " + JSON.stringify(err));
    }
  );
import * as functions from "firebase-functions";
const fs = require("fs");
const { google } = require("googleapis");
const script = google.script("v1");
const scriptId = "MY_SCRIPT_ID";

export const gprocess = functions.https.onCall(async (data: any, context: any) => {
const test = data.test;

return fs.readFile("gapi_credentials.json", (err: any, content: string) => {
  if (err) {return err;}
  const credentials = JSON.parse(content); // load the credentials
  const { client_secret, client_id, redirect_uris } = credentials.web;
  const googleAuth = require("google-auth-library");
  const functionsOauth2Client = new googleAuth.OAuth2Client(client_id, client_secret, redirect_uris); // Constuct an auth client
  functionsOauth2Client.setCredentials({refresh_token: credentials.refresh_token,}); // Authorize a client with credentials
  
  return runScript(functionsOauth2Client,scriptId,JSON.stringify(test))
    .then((scriptData: any) => {
      console.log("Script data in main function is" + JSON.stringify(scriptData));
      return scriptData;
    })
    .catch((error) => {return error;}); 
   });
 });

function runScript(auth: any, scriptid: string, test: any) {
 return new Promise(function (resolve, reject) {
 script.scripts.run({
      auth: auth, 
      scriptId: scriptid,
      resource: {function: "doGet",devMode: true,parameters: test}
    })
  .then((err: any, respons: any) => {
    if (err) {
      console.log("API returned an error: " + JSON.stringify(err));
      resolve(err);
    } else if (respons) {
      console.log("Script is run and response is " + JSON.stringify(respons));
      resolve(respons);
    }
  });
});
}
我的云功能代码如下:

const data = {test: testToProcess};
const process = this.fns.httpsCallable("gprocess"); // fns is Angular Fire Functions
process(data)
  .toPromise() // since Angular Fire function returns an observable, Iam converting to a promise
  .then(
    (result) => {
      console.log("function called: " + JSON.stringify(result));
    },
    (err) => {
      console.log("Function call error " + JSON.stringify(err));
    }
  );
import * as functions from "firebase-functions";
const fs = require("fs");
const { google } = require("googleapis");
const script = google.script("v1");
const scriptId = "MY_SCRIPT_ID";

export const gprocess = functions.https.onCall(async (data: any, context: any) => {
const test = data.test;

return fs.readFile("gapi_credentials.json", (err: any, content: string) => {
  if (err) {return err;}
  const credentials = JSON.parse(content); // load the credentials
  const { client_secret, client_id, redirect_uris } = credentials.web;
  const googleAuth = require("google-auth-library");
  const functionsOauth2Client = new googleAuth.OAuth2Client(client_id, client_secret, redirect_uris); // Constuct an auth client
  functionsOauth2Client.setCredentials({refresh_token: credentials.refresh_token,}); // Authorize a client with credentials
  
  return runScript(functionsOauth2Client,scriptId,JSON.stringify(test))
    .then((scriptData: any) => {
      console.log("Script data in main function is" + JSON.stringify(scriptData));
      return scriptData;
    })
    .catch((error) => {return error;}); 
   });
 });

function runScript(auth: any, scriptid: string, test: any) {
 return new Promise(function (resolve, reject) {
 script.scripts.run({
      auth: auth, 
      scriptId: scriptid,
      resource: {function: "doGet",devMode: true,parameters: test}
    })
  .then((err: any, respons: any) => {
    if (err) {
      console.log("API returned an error: " + JSON.stringify(err));
      resolve(err);
    } else if (respons) {
      console.log("Script is run and response is " + JSON.stringify(respons));
      resolve(respons);
    }
  });
});
}
角度函数在云函数处理完成之前返回此结果。它并不等待从云函数返回结果

detailed.component.ts:691 function called: null
一段时间后,结果会记录在云函数控制台上,但不会返回给angular客户端。云上日志功能如下所示,如下图所示,将记录正确的结果:

5:53:32.633 PM  gpublish Function execution started
5:53:32.694 PM  gpublish Function execution took 61 ms, finished with status code: 204
5:53:33.185 PM  gpublish Function execution started
5:53:33.804 PM  gpublish Function execution took 620 ms, finished with status code: 200
5:54:31.494 PM  gpublish Script is run and response is : {"config":... some result}
5:54:31.593 PM  gpublish Script data in main function is{"config":... some result}

请帮忙

函数未正确返回解析为要序列化并发送到客户端的数据的承诺。问题是这实际上并没有回报一个承诺。它是异步的,不返回任何内容,这就是客户端将收到的内容。正在调用回调,但回调中的任何内容都不会影响客户端看到的内容


您将需要找到另一种执行文件I/O的方法,这种方法可以是同步的(例如),也可以使用承诺,而不仅仅是异步回调。

如上所述,我将代码更改为使用readFileSync(谢谢Doug!) 此外,我对从云函数发送回Angular客户端的数据进行了字符串化

我的云函数现在如下所示:

import * as functions from "firebase-functions";
const fs = require("fs");
const { google } = require("googleapis");
const script = google.script("v1");
const scriptId = "MY_SCRIPT_ID";

export const gprocess = functions.https.onCall(
   async (data: any, context: any) => {
   try {
     const test = data.test;
     const content = fs.readFileSync("credentials.json"); // CHANGED TO READFILESYNC
     const credentials = JSON.parse(content); 
     const { client_secret, client_id, redirect_uris } = credentials.web;
  
     const googleAuth = require("google-auth-library");
     const functionsOauth2Client = ... some code to construct an auth client and authorise it
  
    return runScript(functionsOauth2Client,scriptId,JSON.stringify(test)).then((scriptData: any) => {
    return JSON.stringify(scriptData); // STRINGIFIED THE DATA
    });
 } catch (err) {
  return JSON.stringify(err);
 }
});

  function runScript(auth: any, scriptid: string, test: any) {
    return new Promise(function (resolve, reject) {
   
    script.scripts.run({auth: auth,scriptId: scriptid,resource: {function: "doGet",parameters: test}})
     .then((respons: any) => {resolve(respons.data);})
     .catch((error: any) => {reject(error);});
  });
  }

与同步方法相比,我们应该更喜欢同步方法吗?我知道在这种情况下没有什么不同,但我猜你的建议是不要在服务器上任何我们不需要的地方阻塞。这完全取决于你。不管是哪种方式,您都必须等待文件被读取。谢谢,这帮了大忙!很高兴听到。在堆栈溢出时,通常使用答案左侧的复选标记图标将有用的答案视为正确答案。感谢您让我知道。