我想通过使用Firebase云功能的触发器从外部网址获取数据。但是,获取数据和更新特定节点不起作用。
有什么问题?我的Firebase计划是Blaze。
功能错误:print screen 1
数据库错误:print screen 2
外部数据结构 - JSON
{
"results": [
{
"details_a": "15+ Heavy duty truck comprising of T800 ...",
"equipment_id": "ChIJW6AIkVXemwARTtIvZ2xC3FA"
}
],
"status": "OK"
}
index.js
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const request = require('request');
exports.setDetails = functions.database.ref('/equipment/{pushId}').onWrite((event) => {
if (event.data.previous.exists()) { return }
if (!event.data.exists()) { return }
const post = event.data.val();
if (post.details){ return };
const number = post.number;
const details = '';
request.get({
uri: 'https://api.domain.com/json?partnumber=' + number,
json: true,
headers: {
'Content-Type' : 'application/json' ,
}
}, (error, response) => {
if (error) {
console.error(error);
} else {
details = response.results[0].details_a;
console.log('Response: ', response.headers);
res.status(200).end('OK');
}
});
return admin.database().ref('/equipment/{pushId}').update({number: number, details: details});
});
答案 0 :(得分:0)
request.get()
是异步的,这意味着函数在结果可用之前返回。您提供的回调将在稍后的结果中调用。由于函数立即返回,这意味着函数的最后一行(return
语句)将在调用回调之前执行。尝试将日志语句放入代码的每个部分,以查看实际调用的内容。
由于您在update
之后立即调用Firebase request.get()
方法,但在其结果可用之前,这意味着details
每次都包含一个空字符串。这绝对不是你想要的。
相反,您应该仅在获取完成后更新数据库。为了方便起见,您可能希望使用请求承诺模块来发出一个返回包含结果的承诺的请求,然后将then()
方法链接起来以执行更新。
你仍然必须返回一个只有在所有你的函数中完成异步工作后才能解决的承诺。
还有一个问题。这行代码似乎没有做任何事情:
res.status(200).end('OK');
这看起来像是在HTTP触发器中用来将结果发送到客户端的东西。但是你在这里写一个数据库触发器。我希望这行代码失败,因为res
永远不会在代码中的任何地方定义。
答案 1 :(得分:0)
我遇到了这个问题,我注意到我是在参考实时数据库而不是Firestore。当我更正此错误时,一切都会开始正常工作。
exports.onActionsWrite = functions.firestore
.document('/actions/{id}')
.onWrite(event => {
console.log('I'm here!');
// Do something...
return null;
});
您还可以查看Firestore文档https://firebase.google.com/docs/functions/firestore-events