【问题标题】:Cloud Functions for Firebase interrupted before finishing executionCloud Functions for Firebase 在完成执行前中断
【发布时间】:2017-04-04 21:00:39
【问题描述】:

函数正在观察proposals/{jobid}/{propid}。当一个新的提案被添加,并且child("isinvitation") 为空时,该函数成功地将新节点写入proposals/sent,然后将增量添加到作业jobs/${jobid} 的提案子节点。

删除提案时功能失败。 userRef.child(jobid).remove() 也没有被触发,减少到工作 jobs/${jobid} 的提案子级不会发生。

exports.CountProposals = functions.database.ref("/proposals/{jobid}/{propid}").onWrite((event) => {
    const jobid = event.params.jobid;
    const userId = event.params.propid;
    const isinvitation = event.data.child("isinvitation").val();
    if (!isinvitation) {
        const userRef = admin.database().ref(`users/${userId}/proposals/sent`);
        if (event.data.exists() && !event.data.previous.exists()) {
            userRef.child(jobid).set({
                timestamp: admin.database.ServerValue.TIMESTAMP
            });
        } else if (!event.data.exists() && event.data.previous.exists()) {
            userRef.child(jobid).remove();
        }
    }
    const collectionRef = admin.database().ref(`/jobs/${jobid}`);
                return collectionRef.once('value').then(snapshot => {
                        if (snapshot.val() !== null) {
                            const countRef = collectionRef.child("proposals");
                            countRef.transaction(current => {
                                            if (event.data.exists() && !event.data.previous.exists()) {
                                                            return (current || 0) + 1;
                                            } else if (!event.data.exists() && event.data.previous.exists()) {
                                                            return (current || 0) - 1;
                                            }
                            });
                        }
                });
});

控制台日志不显示任何错误。

【问题讨论】:

    标签: firebase firebase-realtime-database google-cloud-functions


    【解决方案1】:

    您的函数正在尝试在多个位置进行多次写入。这些写入中的每一个都将生成一个不同的承诺来跟踪其完成情况。您应该返回一个在 所有 工作完成后解决的 Promise。就目前而言,您只返回来自 collectionRef.once('value').then() 的一个承诺,它本身并没有返回另一个跟踪交易完成的承诺。

    基本上,您需要小心使用 Promise 跟踪所有写入,通常您使用 Promise.all() 来等待所有未完成的工作。

    【讨论】:

    • 我正在处理 event.data.child("isinvitation").val(); 的空值使用以前的值对我来说没有意义。
    • 我不清楚你的函数应该做什么。你主要是在说它没有在做什么。还要记住,您需要从一个有效的函数中返回一个承诺,例如更新数据库。现在,您没有使用任何从更新(删除、事务)返回的承诺。
    • 该函数做了两件事,当新数据和 isinvitation=false 写入或删除数据库users/${userId}/proposals/sent 中的数据时,然后增加或减少/jobs/${jobid} 中的值建议
    • 我改变了答案。看起来你需要小心返回一个跟踪你所有工作完成的承诺。现在它做的不是很彻底。
    【解决方案2】:

    “每次发生 Firebase 实时数据库写入时触发的事件处理程序。” - https://firebase.google.com/docs/reference/functions/functions.database.RefBuilder#onWrite

    我个人预计这也会在删除操作上触发,但是,它可能类似于 AngularFire,其中 write 操作不被视为 remove 操作。

    您可以看看这个,看看如何让它适应您的情况:https://firebase.google.com/docs/reference/functions/functions.database.DeltaSnapshot#changed

    编辑:在尝试了我自己的一些功能后,它们似乎触发了我的删除。我会更多地研究你的代码。

    【讨论】:

      猜你喜欢
      • 2017-10-09
      • 2017-08-07
      • 2019-05-28
      • 2017-10-09
      • 2018-09-19
      • 2017-09-07
      相关资源
      最近更新 更多