Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase: How to push in transaction?

Tags:

firebase

Say I have the following structure:

{
  "-InSwU2yHOEHwhP_m4_n" : {
    ".priority" : 0.0,
    "name" : "abc"
  },
  "-InSw_P0j8A-0Njj0Uvf" : {
    ".priority" : 1.0,
    "name" : "def"
  }
}

I would like to add another similar item with a guid as a key and priority equals to the number of items currently presented (in this case 2). The result should look something like this:

{
  "-InSwU2yHOEHwhP_m4_n" : {
    ".priority" : 0.0,
    "name" : "abc"
  },
  "-InSw_P0j8A-0Njj0Uvf" : {
    ".priority" : 1.0,
    "name" : "def"
  },
  "-InSxV-RVkZ07_f3uDnJ" : {
    ".priority" : 2.0,
    "name" : "ghi"
  }
}

Note that since multiple clients could try to add such item at the same time, this must be a transaction.

Any ideas?

like image 444
Misha Moroshko Avatar asked Feb 15 '13 13:02

Misha Moroshko


1 Answers

When you use push(), each item is assigned a unique ID. So a transaction wouldn't be necessary (there can't be collisions).

If you want the records to be unique by priority (which looks like what you're trying to accomplish) I think you should simply be using the priority as the ID.

Then you can use a transaction to make sure two clients don't push at the same time:

FB.child(path).transaction(function(current_val) {
   if( current_val === null ) {
      /* set the value here */
   }
   /* do nothing; transaction fails because it was already written */
}, function(success) {
   /* transaction done */
});

However, if you are using the priority as a unique ID, maybe this needs to be rethought; this is really the IDs job and it does a great job; records are also maintained in the order they are inserted so the counter is unnecessary in most cases.

like image 75
Kato Avatar answered Oct 03 '22 11:10

Kato