Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

272
Views
Firebase - One transaction for 2 paths in real time database

I have a database with the following structure:

Structure of my database

Now two paintings can be rated against each other and the rating is then updated. But it can happen that one painting is rated mutliple times at the same time. Therefore i tried using a nested transaction (see below) to avoid race conditions:

function pictureClicked(picture) {
    const db = getDatabase();
    const leftRef = ref(db, '/paintings/' + generateDbName(currentLeft));
    const rightRef = ref(db, '/paintings/' + generateDbName(currentRight));
    const winnerLeft = (picture === 'left') ? 1 : 0;

    runTransaction(leftRef, (leftP) => {
        if (leftP) {
            runTransaction(rightRef, (rightP) => {
                if (rightP) {
                    // Calculation of the new rating for each painting (Elo System)
                    const tRatingLeft = Math.pow(10, leftP.rating / 400);
                    const tRatingRight = Math.pow(10, rightP.rating / 400);

                    const expectedLeft = tRatingLeft / (tRatingLeft + tRatingRight);
                    const expectedRight = tRatingRight / (tRatingLeft + tRatingRight);

                    // Setting new rating
                    leftP.rating = leftP.rating + 32 * (winnerLeft - expectedLeft);
                    rightP.rating = rightP.rating + 32 * ((1 - winnerLeft) - expectedRight);
                }
                return rightP;
            });
        }
        return leftP;
    });
}

Now this solution doesn't really work and I have read that it isn't the best approach to this problem. The only solution I found was running a transaction on the root of my database but I'm afraid that this would lead to a bottleneck and many of the launched transactions wouldn't even write to the database since transactions are only retried 25 times (or is my fear here unfounded?). Are there any other solutions to this problem?

about 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Firebase Realtime Database transactions run against a single path in your database. There is currently no way to run a transaction against multiple path, so the common approach is to run the transaction against the lowest-level shared path (/paintings in your case).

This can indeed lead to more contention as you have more users performing concurrent transactions.


The only alternative I've used at times is to build my own transaction mechanism using:

  1. Multi-path updates, to perform both writes at the same time.
  2. Security rules, to only allow the transition that make sense in my use-case.
  3. Client-side retries, so that contention or outdated data are still handled correctly.

This is fairly non-trivial even for simple cases, and may require changing your data structure and/or adding additional values to each request. But if you get past those hurdles, it will allow you to run a "transaction" across multiple paths.

about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!