繁体   English   中英

firebase function:使用同步 rest 调用更新文档

[英]firebase function : update document with synchronous rest call

我有这个预定的 function :

  1. 从集合中读取 1 个文档

    data: [ { 'field1': 123, 'field2': 456 }, { 'field1': 123, 'field2': 456 }... ]
  2. 循环所有数据数组

  3. 从 rest api 调用读取新值

  4. 更新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++) {})循环中,您实际上是一次又一次地覆盖myFirebaseDatafield1field2属性...

因此,您会在下面找到我认为正确的代码结构/模式,如果不是这样,只需在此答案中添加评论,我们可以根据您将分享的额外细节微调答案。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM