简体   繁体   中英

Can Firebase Transactions ever be wrong?

I have an application that allows users to vote 5 times per day. Each vote is pushed to a votes node. I have an onCreate cloud function listening to votes that kicks off a number of transactions, each one just increments one of several nodes tally/total , tally/users/{userId} , etc.

The voting function and onCreate are tested and working as expected.

Yesterday we deployed to production and I ran a query on tally/users to see if any users found a way to vote more than 5 times in a day. And of course, two users got flagged as having voted 6 times on the first day. So I did a query on the actual votes node and found that those users had actually only submitted 5 votes. So... my transactions didn't work right for two out of over 5000 users.

For our case, we don't really need these counters to be super accurate but, what's the deal? Am I missing something about firebase transactions or can they really not be counted on? (pun intended)

Don't make fun of my poorly structured db...

exports.allVotesOnCreate = functions.database
  .ref('/votes/all/{pushId}')
  .onCreate(
    (snapshot, context) => {
      const vote = snapshot.val();
      const { date, userId, uid } = vote;

      return Promise.all([
        // removed other transactions for brevity
        ref(`tally/all/total`)
          .transaction(value => 
            value ? value + 1 : 1
        ),
        ref(`tally/user/byDate/${userId}/${date}`)
          .transaction(value =>
            value ? value + 1 : 1
        ),
      ]).catch(err => {
        console.error(`Error tallying vote ${uid}`, err);
      });
    }
  );

I expected that the number of votes in votes for a specific user on a specific date would match their tally in tally/user/byDate/{userId}/{date} , but there are a small number of incidents where the tally is 6 when the actual number of votes is 5.

I could even expect that the tally could be less than the actual number of votes, if a transaction somehow failed, but more? how?

With Cloud Functions, an event might be delivered multiple times if there is some unexpected failure in the system. As such, your function should expect that that your function handle could be invoked more than once per database change. This is rare but possible. It's up to you to (if you want) to detect these duplicate invocations and handle the appropriately.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM