【问题标题】:Firebase Cloud Functions set value operation deletes the trigger originating nodeFirebase Cloud Functions 设置值操作删除触发器始发节点
【发布时间】:2018-11-04 09:45:51
【问题描述】:


您好,以上是我在 firebase 实时数据库中的简单数据结构。我正在开发一个简单的云函数,它将侦听用户节点“score”属性中的更新并更新位于层次结构较高的“averageScore”字段。

这是我的 onWrite 回调:

.onWrite((change, context) => {

    if (!change.before.exists() || !change.after.exists()) {
        return null;
    }

    const beforeScore = parseFloat(change.before.val()['score']);
    const afterScore = parseFloat(change.after.val()['score']);
    const userRef = change.after.ref;

    var promises = [
        userRef.parent.parent.child('userCount').once('value'),
        userRef.parent.parent.child('averageScore').once('value')
    ];

    return userRef.transaction(() => {
        return Promise.all(promises).then((snapshots) => {
            const userCount = snapshots[0].val();
            const averageScore = snapshots[1].val();

            const currentAverage = (( ( averageScore * userCount ) - beforeScore + afterScore ) / userCount ).toFixed(2);

            return userRef.parent.parent.child('averageScore').set(currentAverage);
        });
    });

});

如果我更新 userId 1234 的 score,则 averageScore 字段会根据此代码正确更新。但是,在此更新之后,整个用户 ID 节点 1234 将被DELETED。这是一个相当令人头疼的问题,并希望从社区中获得一些关于我可能做错了什么的见解。

干杯。

【问题讨论】:

  • 我认为您误解了事务如何与实时数据库一起工作。这里有很多问题(包括在事务中使用set(),以及到达事务本身的位置之外。
  • @DougStevenson 是的,我的误解完全正确。想通了并发布了答案。谢谢。

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


【解决方案1】:
.onWrite((change, context) => {

    if ( !change.before.exists() || !change.after.exists()) {
        return null;
    }

    const beforeScore = parseFloat(change.before.val()['score']);
    const afterScore = parseFloat(change.after.val()['score']);
    const crowdStatsRef = change.after.ref.parent.parent.child('crowdStats');

    return Promise.all( [
        crowdStatsRef.child('userCount').once('value'),
        crowdStatsRef.child('averageScore').once('value')
    ]).then((snapshots) => {
        return crowdStatsRef.transaction((crowdStatsNode) => {

            if (crowdStatsNode) {
                const userCount = snapshots[0].val();
                const averageScore = snapshots[1].val();

                const currentAverage = (( ( averageScore * userCount ) - beforeScore + afterScore ) / userCount ).toFixed(2);
                crowdStatsNode.score = parseFloat(currentAverage);
            }

            return crowdStatsNode;
        }, (error, committed, snapshot) => {
            if (error) {
                console.error(error);
            }
        });
    });
});

误解了交易的运作方式。您锁定的对象必须在回调函数中返回。此外,该回调函数中的空检查在这里是必不可少的。

示例如下: https://firebase.googleblog.com/2016/01/keeping-our-promises-and-callbacks_76.html

【讨论】:

    猜你喜欢
    • 2017-10-01
    • 2017-09-25
    • 2017-10-18
    • 2018-10-16
    • 1970-01-01
    • 2017-12-18
    • 1970-01-01
    相关资源
    最近更新 更多