我知道这个问题已被问过几次,但解决方案并不适用于我的情况。我使用以下两个命令启动了ElasticSearch
,Kibana
:
bin/elasticsearch
bin/kibana
服务器运行良好,使用浏览器转到http://localhost:9200
时,我得到以下结果:
{
"name" : "vg7RnLh",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "gqDf0H67TxGZGYigAlu2mQ",
"version" : {
"number" : "6.1.2",
"build_hash" : "5b1fea5",
"build_date" : "2018-01-10T02:35:59.208Z",
"build_snapshot" : false,
"lucene_version" : "7.1.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
使用kibana
时,一切正常。这是我写的firebase云功能,如果有什么不对的话,我认为它在这里:
exports.downloadUserInfo = functions.https.onRequest((req, res) => {
const { uid } = req.query;
const searchConfig = {
uri: 'http://localhost:9200/users/user/' + uid,
method: 'GET'
};
request(searchConfig)
.then((result) => {
console.log(result);
return res.status(200).send(result);
})
.catch((error) => {
console.log(error);
return res.status(400).send(error);
});
});
request
是由yarn add request request-promise
安装的模块。然后,当使用Postman
来测试我的API时,我收到此错误:
如何解决此问题?
更新
我还使用命令flashlight
运行node app.js
。将新用户插入数据库时,新用户也会自动插入ElasticSearch服务器(localhost),但是,当我尝试读取时,会抛出请求错误
第二次更新
这是创建用户的API:
exports.register = functions.https.onRequest((req, res) => {
const { firstName, lastName } = req.body;
admin.database().ref('users').push({ firstName, lastName })
.then(() => res.status(201).send())
.catch(() => res.status(400).send());
});
当此API创建新用户时,此用户会自动插入我的localhost ElasticSearch服务器,因为我使用的是flashlight
插件。我不明白为什么当我尝试从同一台服务器上读取时,会出现请求错误。
答案 0 :(得分:2)
您的代码正在尝试访问本地主机:
-pubnub.com
这不起作用:您不能只访问运行Cloud Functions的容器上的“随机”端口。
我的猜测是你在本地机器上运行ElasticSearch,这就是uri: 'http://localhost:9200/users/user/' + uid,
所指的内容。但是要在云功能环境中运行代码,您需要在可公开访问的系统上运行ElasticSearch,并在localhost
中指定该计算机的IP。
答案 1 :(得分:2)
云功能在Google控制的服务器上运行。它们不能在您的计算机上运行(除非您使用本地仿真进行测试)。
您的功能是访问“localhost”的网址:
const searchConfig = {
uri: 'http://localhost:9200/users/user/' + uid,
method: 'GET'
};
request(searchConfig).then(...)
在几乎每个上下文中,localhost表示IP地址127.0.0.1 - 运行代码的机器。当您的代码在云功能中运行时,这意味着localhost是运行代码的Google服务器实例。这肯定不是您想要的,不幸的是,您将无法访问在您的个人计算机上运行的服务。
答案 2 :(得分:1)
这是答案。正如Frank van Puffelen和Doug Stevenson指出的那样,无论如何,我都无法从已部署的firebase函数向localhost服务器执行任何请求。
但是在flashlight
插件的帮助下,我可以让我的localhost服务器知道我现在要执行搜索操作。我所做的是config.js
文件夹flashlight
文件夹中的文件:
exports.FB_REQ = 'search/request';
exports.FB_RES = 'search/response';
这两行的作用是告诉我的数据库在数据库中创建一个名为search
的表,该表有2个子表,一个名为request
,另一个名为response
。 flashlight
将监视您的firebase数据库并更新ES服务器中的任何数据,除了您写入search/request
表的内容。当您写入此表时,flashlight
会检测到它,并且它知道您现在要执行搜索操作,它将运行您在ES服务器上放置的查询,然后将结果存储在search/response
表,您只需要听取该表中的更新,这将是您的搜索结果。
新的downloadUserInfo
API应该是这样的:
exports.downloadUserInfo = functions.https.onRequest((req, res) => {
const { uid } = req.query;
const key = admin.database().ref('search/request')
.push({ index: 'users', type: 'user', q: uid }).key;
admin.database().ref(`search/response/${key}`).once('value')
.then((snapshot) => {
return res.status(200).send(snapshot.val());
})
.catch((error) => {
return res.status(400).send(error);
});
});