![](/img/trans.png)
[英]Firebase Function query and update a single Firestore document
[英]firebase function : update document with synchronous rest call
我有这个预定的 function :
从集合中读取 1 个文档
data: [ { 'field1': 123, 'field2': 456 }, { 'field1': 123, 'field2': 456 }... ]
循环所有数据数组
从 rest api 调用读取新值
更新firestore中数据数组的值
来自 firebase function 控制台日志的注意事项我在日志“ firebase 文档更新... ”之后有日志“字段更新...”,我认为是因为请求未同步文档更新...
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const db = admin.firestore();
const fetch = require('node-fetch');
var request = require("request");
const { Headers } = fetch;
exports.onStatisticUpdated = functions.region('europe-west1')
.runWith({
timeoutSeconds: 300,
})
.pubsub.schedule('every 60 minutes')
.onRun(async context => {
const doc = await admin
.firestore()
.collection('collection')
.doc('1234')
.get();
if (doc.exists) {
for (let i = 0; i < doc.data().data.length; i++) {
let myFirebaseData = doc.data().data[i];
var options = {
method: 'GET',
url: 'https://xyz....',
qs: { abcd: 'value' },
headers: {
'x-xxxx-host': 'v1....',
'x-xxxx-key': 'xxxxxxxxxxxx'
}
}
request(options, function (error, response, body) {
if (error) throw new Error(error);
var json = JSON.parse(body);
if (json['response'].length > 0) {
console.log('field updated ...');
myFirebaseData.field1 = json['response'][0].value1
myFirebaseData.field2 = json['response'][0].value2
};
});
}
// myFirebaseData is not updated at this time with new value filled by rest api !!!
console.log(' firebase document updated ...');
await admin
.firestore()
.collection('collection')
.doc('1234')
.update({
data: doc.data(),
});
}
});
问题:如何使用由 rest api 填充的新值存储最终文档?
在 Cloud Functions 中,您需要通过 Promises 管理异步方法调用(文档中 的更多详细信息)。 request
原生支持回调接口,但不返回 Promise 。
您应该使用另一个库,例如axios 。 此外,由于要并行执行可变数量的异步 Rest API 调用,因此需要使用Promise.all()
。
现在,我在您的代码中不清楚的是如何构建用于更新1234
文档的 object。 在您当前的代码中,在for (let i = 0; i < doc.data().data.length; i++) {})
循环中,您实际上是一次又一次地覆盖myFirebaseData
的field1
和field2
属性...
因此,您会在下面找到我认为正确的代码结构/模式,如果不是这样,只需在此答案中添加评论,我们可以根据您将分享的额外细节微调答案。
exports.onStatisticUpdated = functions.region('europe-west1')
.runWith({
timeoutSeconds: 300,
})
.pubsub.schedule('every 60 minutes')
.onRun(async context => {
const doc = await admin
.firestore()
.collection('collection')
.doc('1234')
.get();
if (doc.exists) {
const promises = [];
for (let i = 0; i < doc.data().data.length; i++) {
let myFirebaseData = doc.data().data[i];
var options = {
method: 'get',
url: 'https://xyz....',
params: { abcd: 'value' },
headers: {
'x-xxxx-host': 'v1....',
'x-xxxx-key': 'xxxxxxxxxxxx'
}
}
promises.push(axios(options))
}
apiResponsesArray = await Promise.all(promises);
const updateObject = {};
apiResponsesArray.forEach((resp, index) => {
// THIS ENTIRE BLOCK NEEDS TO BE ADAPTED!!
// I'M JUST MAKING ASSUMPTIONS...
const responseData = resp.data;
updateObject["field1" + index] = responseData.value1;
updateObject["field2" + index] = responseData.value2;
})
console.log(updateObject)
console.log(' firebase document updated ...');
await admin
.firestore()
.collection('collection')
.doc('1234')
.update({
data: updateObject
});
return null; // IMPORTANT!!! see the link to the doc above
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.