【问题标题】:Data not saved into Firestore through scheduler function with Firebase Cloud Functions数据未通过 Firebase Cloud Functions 的调度程序功能保存到 Firestore
【发布时间】:2022-08-19 16:57:58
【问题描述】:

我正在尝试使用 Firebase Cloud Functions 创建 API,以便构建一个系统,使通过 API 收集的内容和其他第三方 API 定期保存到 Firestore。这是我此刻的源代码index.js,我想控制这个文件中的所有进程。

/functions/index.js

const firebaseAdmin = require(\"firebase-admin\");
const firebaseFunctions = require(\"firebase-functions\");
firebaseAdmin.initializeApp();
const fireStore = firebaseAdmin.firestore();

const express = require(\"express\");
const axios = require(\"axios\");
const cors = require(\"cors\");

const serviceToken = \"SERVICE-TOKEN\";
const serviceBaseUrl = \"https://api.service.com/\";

const app = express();
app.use(cors());

const getAllExamples = async () => {
    var url = `${serviceBaseUrl}/examples?token=${serviceToken}`;
    var config = {
        method: \"get\",
        url: url,
        headers: {}
    };
    axios(config).then((res) => {
        console.log(\"Data saved!\");
        return res.data;
    }).catch((err) => {
        console.log(\"Data not saved: \", err);
        return err;
    });
}

const setExample = async (documentId, dataObject) => {
    fireStore.collection(\"examples\").doc(documentId).set(dataObject).then(() => {
        console.log(\"Document written!\");
    }).catch((err) => {
        console.log(\"Document not written: \", err);
    });
}

app.get(\"/getAllExamples\", (req, res) => {
    getAllExamples().then((response) => res.send(response));
});

app.put(\"/setExample\", (req, res) => {
    setExample(req.params.documentId).then((response) => res.send(response));
});

const api = firebaseFunctions.https.onRequest(app);
module.exports = { api };

module.exports.updateExamplesRoutinely = firebaseFunctions.pubsub.schedule(\"0 0 * * *\").timeZone(\"America/Los_Angeles\").onRun((context) => {
    var examples = getAllExamples();
    for(var i = 0; i < examples.length; i++) {
        var example = examples[i];
        var exampleId = example[\"id\"];
        if(exampleId && example) setExample(exampleId, example);
    }
});

因此,updateExamplesRoutinely 在太平洋标准时间每 00:00 正确触发,但没有数据存储在 Firebase 中,也没有关于 Firebase 数据更新的控制台日志,也没有在 Cloud Functions 日志中找到。

通过https://api.service.com/ 收集的输出数据如下所示:

[
  {
    id: \"BB345\",
    name: \"Tim Gordon\",
    age: 24,
    email: \"tgordon@yahoo.com\"
  },
  {
    id: \"CC098\",
    name: \"John Doe\",
    age: 28,
    email: \"john.doe@gmail.com\"
  },
  {
    id: \"DD777\",
    name: \"Adam Smith\",
    age: 39,
    email: \"adamsmith@outlook.com\"
  },
  ...
]

简单地说,这三个问题是我想要解决的。

  1. 我应该如何通过 Cloud Functions\' 调度程序调用在index.js 中定义的 API?
  2. 我应该如何将数据保存到 Cloud Functions\' 调度程序内的 Firestore?
  3. 调用第三方 API、等待并收集结果并将其传递给其他事件或函数的最佳“异步”方式是什么?

    标签: node.js firebase express axios google-cloud-functions


    【解决方案1】:

    我应该如何通过 Cloud Functions 调用 index.js 中定义的 API 调度器?

    我猜你想说“我应该怎么打电话方法在 index.js 中定义”。没有理由从同一个 Cloud Function 调用 Cloud Function 公开的 API。

    因此,要调用这些方法,请执行以下操作:

    const getAllExamples = async () => {
        var url = `${serviceBaseUrl}/examples?token=${serviceToken}`;
        var config = {
            method: "get",
            url: url,
            headers: {}
        };
        return axios(config).then((res) => {   // !!! note the return here
            console.log("Data saved!");
            return res.data;
        }).catch((err) => {
            console.log("Data not saved: ", err);
            return err;
        });
    }
    
    const setExample = async (documentId, dataObject) => {
        // !!! note the return on next line
        return fireStore.collection("examples").doc(documentId).set(dataObject).then(() => {
            console.log("Document written!");
        }).catch((err) => {
            console.log("Document not written: ", err);
        });
    }
    
    module.exports.updateExamplesRoutinely = firebaseFunctions.pubsub.schedule("0 0 * * *").timeZone("America/Los_Angeles").onRun(async (context) => {
        const examples = await getAllExamples();
    
        const promises = [];
        for(var i = 0; i < examples.length; i++) {
            var example = examples[i];
            var exampleId = example["id"];
            if(exampleId && example) promises.push(setExample(exampleId, example));
        }
        return Promise.all(promises);
        // See how we return the promise returned by Promise.all
        // !!! This is IMPORTANT, see https://firebase.google.com/docs/functions/terminate-functions 
    
    });
    

    我应该如何将数据保存到 Cloud Functions 内的 Firestore 中 调度器?

    上面的代码会将数据保存在 Firestore 中。你实际上想要对setExample()方法执行可变数量的调用,你需要使用Promise.all(),如上图所示。这样,setExample() 将为每个 example 写入 Firestore。

    调用第三方 API 的最佳“异步”方式是什么,等待并 收集结果,并将它们传递给其他事件或函数?

    看看我们如何调整updateExamplesRoutinely 云函数:我们使用asyncawait 关键字。

    module.exports.updateExamplesRoutinely = firebaseFunctions.pubsub.schedule("0 0 * * *").timeZone("America/Los_Angeles").onRun(async (context) => {
        const examples = await getAllExamples();
        // ...
    

    【讨论】:

      猜你喜欢
      • 2018-10-16
      • 1970-01-01
      • 2019-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-01
      • 2018-12-06
      • 1970-01-01
      相关资源
      最近更新 更多