我正在使用云功能在免费火花层上调用另一个云功能。
是否有一种特殊方式可以调用另一个云功能?或者您只是使用标准的http请求?
我试过直接调用另一个函数:
exports.purchaseTicket = functions.https.onRequest((req, res) => {
fetch('https://us-central1-functions-****.cloudfunctions.net/validate')
.then(response => response.json())
.then(json => res.status(201).json(json))
})
但是我收到了错误
FetchError:请求 https://us-central1-functions- ****。cloudfunctions.net/validate 失败,原因:getaddrinfo ENOTFOUND 美国central1 - 功能 - ***** cloudfunctions.net。 US-central1函数 - ***** cloudfunctions.net:443
尽管它是google拥有的,但像firebase这样的声音阻止了连接,因此它不应该被锁定
Spark计划仅允许向Google拥有的出站网络请求 服务。
如何使用云功能调用另一个云功能?
答案 0 :(得分:14)
您无需通过全新的HTTPS调用来解决调用某些共享功能的麻烦。您可以简单地将代码的常见位抽象为一个由任一个调用的常规javascript函数。例如,您可以像这样修改模板helloWorld函数:
var functions = require('firebase-functions');
exports.helloWorld = functions.https.onRequest((request, response) => {
common(response)
})
exports.helloWorld2 = functions.https.onRequest((request, response) => {
common(response)
})
function common(response) {
response.send("Hello from a regular old function!");
}
这两个函数将完全相同,但具有不同的端点。
答案 1 :(得分:3)
要回答该问题,您可以执行https请求以调用另一个云函数:
export const callCloudFunction = async (functionName: string, data: {} = {}) => {
let url = `https://us-central1-${config.firebase.projectId}.cloudfunctions.net/${functionName}`
await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ data }),
})
}
(请注意,我们将npm软件包“ node-fetch”用作我们的提取实现。)
然后简单地称呼它:
callCloudFunction('search', { query: 'yo' })
这样做是有正当理由的。我们使用它来每分钟ping我们的搜索云功能并保持其运行。这样可以大大降低响应延迟,每年只需几美元。
答案 2 :(得分:0)
通过包含授权令牌,可以通过HTTP调用另一个Google Cloud Function。它需要一个主要的HTTP请求来计算令牌,然后在调用要运行的实际Google Cloud Function时使用该令牌。
https://cloud.google.com/functions/docs/securing/authenticating#function-to-function
const {get} = require('axios');
// TODO(developer): set these values
const REGION = 'us-central1';
const PROJECT_ID = 'my-project-id';
const RECEIVING_FUNCTION = 'myFunction';
// Constants for setting up metadata server request
// See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature
const functionURL = `https://${REGION}-${PROJECT_ID}.cloudfunctions.net/${RECEIVING_FUNCTION}`;
const metadataServerURL =
'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=';
const tokenUrl = metadataServerURL + functionURL;
exports.callingFunction = async (req, res) => {
// Fetch the token
const tokenResponse = await get(tokenUrl, {
headers: {
'Metadata-Flavor': 'Google',
},
});
const token = tokenResponse.data;
// Provide the token in the request to the receiving function
try {
const functionResponse = await get(functionURL, {
headers: {Authorization: `bearer ${token}`},
});
res.status(200).send(functionResponse.data);
} catch (err) {
console.error(err);
res.status(500).send('An error occurred! See logs for more details.');
}
};
答案 3 :(得分:0)
尽管有问题标签和其他答案,但我想分享该示例的javascript脚本,因为它反映了问题中提到的标题和身份验证方面。
Google Cloud Function提供REST API interface可以在另一个Cloud Function中使用的包含调用方法。 尽管文档mention using Google-provided client libraries仍然没有关于Python的Cloud Function的文档。
相反,您需要使用常规的Google API客户端库。 [这是python的一个。] 3
使用这种方法的主要困难可能是对身份验证过程的理解。 通常,您需要提供两件事来构建客户端服务: 凭据和范围。
获取凭据的最简单方法是在应用程序默认凭据(ADC)库上进行中继。有关的严格文档是:
获取范围的地方是每个REST API函数文档页面。 像OAuth scope: https://www.googleapis.com/auth/cloud-platform
下面是调用'hello-world'clound功能的完整代码示例。 运行之前:
from googleapiclient.discovery import build
from googleapiclient.discovery_cache.base import Cache
import google.auth
import pprint as pp
def get_cloud_function_api_service():
class MemoryCache(Cache):
_CACHE = {}
def get(self, url):
return MemoryCache._CACHE.get(url)
def set(self, url, content):
MemoryCache._CACHE[url] = content
scopes = ['https://www.googleapis.com/auth/cloud-platform']
# If the environment variable GOOGLE_APPLICATION_CREDENTIALS is set,
# ADC uses the service account file that the variable points to.
#
# If the environment variable GOOGLE_APPLICATION_CREDENTIALS isn't set,
# ADC uses the default service account that Compute Engine, Google Kubernetes Engine, App Engine, Cloud Run,
# and Cloud Functions provide
#
# see more on https://cloud.google.com/docs/authentication/production
credentials, project_id = google.auth.default(scopes)
service = build('cloudfunctions', 'v1', credentials=credentials, cache=MemoryCache())
return service
google_api_service = get_cloud_function_api_service()
name = 'projects/{project_id}/locations/us-central1/functions/function-1'
body = {
'data': '{ "message": "It is awesome, you are develop on Stack Overflow language!"}' # json passed as a string
}
result_call = google_api_service.projects().locations().functions().call(name=name, body=body).execute()
pp.pprint(result_call)
# expected out out is:
# {'executionId': '3h4c8cb1kwe2', 'result': 'It is awesome, you are develop on Stack Overflow language!'}
答案 4 :(得分:0)
这些建议似乎不再有效。
为了让它对我有用,我使用 httpsCallable 从客户端进行调用并将请求导入邮递员。还有一些指向 https://firebase.google.com/docs/functions/callable-reference 的其他链接很有帮助。但是要确定信息的可用位置需要花点时间弄清楚。
我在这里写下了所有内容,因为它需要一些解释和一些示例。
https://www.tiftonpartners.com/post/call-google-cloud-function-from-another-cloud-function
这是“url”的内联版本可能会过期。
这“应该”有效,它没有经过测试,而是基于我为自己的应用程序编写和测试的内容。
module.exports = function(name,context) {
const {protocol,headers} = context.rawRequest;
const host = headers['x-forwardedfor-host'] || headers.host;
// there will be two different paths for
// production and development
const url = `${protocol}://${host}/${name}`;
const method = 'post';
const auth = headers.authorization;
return (...rest) => {
const data = JSON.stringify({data:rest});
const config = {
method, url, data,
headers: {
'Content-Type': 'application/json',
'Authorization': auth,
'Connection': 'keep-alive',
'Pragma': 'no-cache,
'Cache-control': 'no-cache',
}
};
try {
const {data:{result}} = await axios(config);
return result;
} catch(e) {
throw e;
}
}
}
这就是你调用这个函数的方式。
const crud = httpsCallable('crud',context);
return await crud('read',...data);
context 你从谷歌云入口点获得,是最重要的部分,它包含对你的云函数进行后续调用所需的 JWT 令牌(在我的例子中是它的 crud) >
要定义另一个 httpsCallable 端点,您可以编写如下导出语句
exports.crud = functions.https.onCall(async (data, context) => {})
它应该像魔术一样工作。
希望这会有所帮助。
答案 5 :(得分:0)
扩展 Shea Hunter Belsky 的回答我很想通知您,调用 google 的元数据服务器以获取授权令牌在本地机器上不起作用