【问题标题】:Firebase Cloud Funtion call trigger mutiple timeFirebase Cloud Function 调用触发多次
【发布时间】:2020-04-02 05:57:06
【问题描述】:

我使用 firebase 并创建触发器来监听学生文档的任何更改。如果学生文档发生更改,我会将任何更改推送到 rest api。但是我的函数调用了多次。

下面是我的功能:

exports.triggerTimeStudent= functions.firestore
    .document('users/{userId}/class/{classId}/students/{studentId}')
    .onUpdate( (change, context) => {
        const newValue = change.after.data();
        const previousValue = change.before.data();
        const {update_at: afterStatus} = newValue;
        const {update_at: beforeStatus} = previousValue;
        const {name: name} = newValue;
        if (afterStatus !== beforeStatus) {
                try {

                    var data = {
                        "student_name": name,
                    };
                    console.log(data);
                    console.log("Inside Rest API");
                    return rest.post("https://example.com/api/v1/student/add-by-name", {
                        ...studentServiceRestOption, ...{
                            body:  JSON.stringify(data)
                        }
                    });

                } catch (error) {
                    return res
                        .status(HttpStatus.INTERNAL_SERVER_ERROR)
                        .send(buildError({
                            code: errorCode.SYSTEM_ERROR,
                            message: error.message,
                        }))
                }

        }

我不知道为什么函数调用多次。我只想打电话给时间。我的功能不正确。请帮忙

【问题讨论】:

  • 我希望这个功能根本不起作用。您不能在 Firestore 函数中调用 res.send()。这仅适用于 HTTP 函数。
  • @DougStevenson 但它会在 example.com/api/v1/student/add-by-name 中创建成功学生姓名。它只在服务器出错时调用 res.send。它创造了成功,但它创造了两次。这意味着它两次调用触发器。我不知道为什么?请帮忙
  • @DougStevenson 当我删除 try catch 并只调用 rest 时,它创建了成功但创建了重复数据。当我在 Cloud Funtion 中查看日志时,它会调用多次触发
  • @DougStevenson 如何在触发器中调用rest api?

标签: node.js firebase google-cloud-platform google-cloud-firestore google-cloud-functions


【解决方案1】:

根据设计,Cloud Functions 可能会被多次调用。确保您的函数可以处理being retried,这取决于您。

但是,您的错误可能源于 update_at 键的值。如果这个键的值是一个对象,===!== 操作数不会产生正确的结果。您需要检查对象的“isEqual”或“equals”方法,或使用第三方解决方案,例如_.isEqual

在下面,我已重构您的代码以提高性能和易用性。我无法识别您用于 API 调用的 rest 对象,因此我将其替换为 node-fetch

const fetch = require("node-fetch"); // see https://www.npmjs.com/package/node-fetch

// for object equality tests
// const isEqual = require("lodash.isequal");

const STUDENT_SERVICE_DEFAULT_OPTIONS = {
  method: "post",
  headers: {
    "Content-Type": "application/json"
  }
}

exports.triggerTimeStudent= functions.firestore
    .document("users/{userId}/class/{classId}/students/{studentId}")
    .onUpdate( (change, context) => {
        const beforeStatus = change.before.get("update_at"); // accessed directly for performance
        const afterStatus = change.after.get("update_at");

        // If beforeStatus and afterStatus are
        //  - string, boolean, int, etc.: use beforeStatus === afterStatus
        //  - firestore.Timestamp objects: use beforeStatus.isEqual(afterStatus)
        //  - custom objects: use isEqual(beforeStatus, afterStatus) from lodash/underscore packages

        if (beforeStatus === afterStatus) {
          console.log("Status unmodified. Ignored change.");
          return;
        }

        const data = {
          student_name: change.after.get("name")
        }

        console.log("Making API call...", { data });

        const fetchOptions = {
          ...STUDENT_SERVICE_DEFAULT_OPTIONS,
          body: JSON.stringify(data)
        }

        return fetch("https://example.com/api/v1/student/add-by-name", fetchOptions)
          .then(response => {
            if (!response.ok) { // see "Handling client and server errors" in "node-fetch" docs
              throw new Error("Unexpected API response: " + response.statusText);
            }

            console.log("Successfully added student!");
          })
          .catch(error => console.error("Failed to add student!", { error, fetchOptions }));
    });

注意:您可以在Firebase console 中查看来自 Cloud Functions 的记录消息。

【讨论】:

    猜你喜欢
    • 2018-05-16
    • 2020-10-26
    • 2018-06-25
    • 2019-08-18
    • 2022-08-16
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    相关资源
    最近更新 更多