使用Cloud Functions for Firebase一致地聚合值

时间:2017-04-12 16:49:30

标签: firebase aggregate google-cloud-functions

我正在尝试创建存储在路径中的“未读消息”总数,例如

/messages/{my_id}/{friend_id}

通过创建在上述路径触发的云功能,当它被触发时,它将更新此路径:

/unread-messages-count/{my_id}

因此,如果/messages/123包含以下数据:

{
   "200": { "msg1": "...", "msg2": "..." },
   "201": { "msg3": "...", "msg4": "...", "msg5": "..." },
}

我希望/unread-messages-count/123最终拥有值5

"201"子树设置为null时,我希望/unread-messages-count/123最终得到值2

值必须一致,所以我在一个Cloud Function中使用了事务,并在/messages/{my_id}/{friend_id}上使用了onWrite触发器:

onWrite((event) => {
     let oldCount = event.data.previous.numChildren;
     let newCount = event.data.current.numChildren;
     let delta = newCount - oldCount;

     let p = db.ref(`/unread-messages-count/${event.params.my_id}`).transaction((data) => {
         let oldTotal = !data ? 0 : data;
         let newTotal = oldTotal + delta;
         return newTotal;
     });

     return Promise.all([p])
        .then(() => { console.log('success'); });
}

到目前为止,它完美地运行(当有大量并发写入时,事务会被重试几次),但今天我遇到了一个奇怪的情况:current包含0个孩子而previous包含5个儿童,导致未读计数总数发生-5次更改,但几秒钟后再次出现相同情况,导致未读计数总数发生另外-5次更改,使其无效。

由于某种原因,似乎onWrite回调被触发了两次。这可能发生吗?

这样做的替代方法是什么?

0 个答案:

没有答案