1

I am trying to determine if my transaction pattern is correct in my Cloud Function. As I understand, you should limit updates to child nodes. So I've tried to follow that general rule.

/functions/index.js

//not rate limited
//writes:
// - board.posts+1
// - thread.replies+1
// - thread.pages+1 if page count should change Math.ceil(thread.replies+1/POSTS_PER_PAGE)=pages
exports.newPost2 = require('./lib/new-post-2')(functions,firebase,rootRef,POSTS_PER_PAGE);

/functions/lib/new-post-2.js

module.exports = function(functions,firebase,rootRef,POSTS_PER_PAGE){

    return functions.database.ref('/posts/{forum}/{board}/{thread}/{post}').onWrite(function(event){

        // Only edit data when it is first created.
        if (event.data.previous.exists()) {
            return;
        }
        // Exit when the data is deleted.
        if (!event.data.exists()) {
            return;
        }

        var params = event.params;
        var forum = params.forum;
        var board = params.board;
        var thread = params.thread;
        var post = params.post;

        //first increment the replies node of the thread.
        rootRef.child('threads').child(forum).child(board).child(thread).child('replies').transaction(function(data) {

            return data + 1;//increment reply count for thread. 

        }).then(function(snapshot){
            //now, our snapshot should contain the updated value of replies.
            var replies = snapshot.val();

            //update the page count of the thread
            rootRef.child('threads').child(forum).child(board).child(thread).child('pages').transaction(function(data) {
                return Math.ceil(replies+1/POSTS_PER_PAGE);//replies is always +1 because OP of thread doesnt count as a reply.
            });

            //update the posts count for the board. this field is also updated by another firebase cloud function, when a thread is created
            rootRef.child('forums').child(forum).child('boards').child(board).child('posts').transaction(function(data){
                return data + 1;//increment post count for the board.
            });
        }); 

    });
};

I'm worried about possibly racing while updating page count of thread and post count of board after the initial reply field is incremented on thread. I'm wondering if there is a safer way I can restructure this to update all 3 fields within the first transaction, if its possible.

AL.
  • 36,815
  • 10
  • 142
  • 281
r3wt
  • 4,642
  • 2
  • 33
  • 55
  • See my answer here for the general approaches: http://stackoverflow.com/a/30699277/209103 In this case,I'd consider a multi-location update, instead of nested transactions. To ensure consistency, you might be able to write some advanced security rules such as I did here: http://stackoverflow.com/a/37956590/209103 – Frank van Puffelen Apr 13 '17 at 05:17
  • @FrankvanPuffelen I read the answer, but it doesn't really help me. I'm doing other fan outs that don't care about consistency, such as throttled (every 20s max per thread) notifications. In these cases, last write wins and it doesnt matter. but in my question, each write needs to happen atomically so that the data is always accurate. – r3wt Apr 13 '17 at 05:51

0 Answers0