Search code examples
databasefirebaserollbackundo

Firebase - right way to implement an undoable .update()?


I'm just learning Firebase and noticed that any operation simply replaces the data, which is a bit different than what I've seen on couchDB.

In my understanding of their documentation, for purposes of making a rollback/undo of an .update() operation possible, I would use the .push() method. The idea would be to keep 2 versions of the data, so that I can query for the previous object. TO boot, there would need to be a FILO kind of approach so I'm not storing more than 2 items.

DATABASE BEFORE FIRST WRITE:

myData
+ someObject
  - keyOne : valueOne
  - keyTwo : valueTwo

DATABASE AFTER FIRST WRITE ref.child(someObject).update({keyOne:valueOneUpdated}):

myData
+ someObject
  - keyOne : valueOneUpdated
  - keyTwo : valueTwo

The above is NOT the desired result, since I lost the previous version of the item.

DATABASE AFTER FIRST WRITE ref.child(keyOne).push({keyOne:valueOneUpdated}):

myData
+ someObject
  + keyOne
    + 1k34jh23kj4h : valueOneUpdated
    + 237we8sjkdf8 : valueOne
  - keyTwo : valueTwo

Yuck! As there is no pop() method to remove the last item of such an operation, I'm now faced with having to somehow figure out which is the first and which is the last item.

Surely there must be some elegant and straightforward way to make rollback possible, no? What am I missing?

Thanks.


Solution

  • If the goal is to have a single level of undo, it's pretty straightforward.

    myData
      someObject
        keyOne
          currentValue: valueOneUpdated
          priorValue: valueOne
        keyTwo
          currentValue: valueTwo
    

    If the priorValue node exists then allow the undo, and move it's value to the currentValue and then remove prior value.

    You could expand on this with adding multiple undos by leveraging an array in Firebase

    myData
      someObject
        keyOne
          currentValue: valueOneUpdated
          priorValues: 
               0: prior_value_3 //the value just prior to valueOneUpdated
               1: prior_value_2
               2: prior_value_1         
    

    (conceptually) The most recent priorValue is at index 0 so read it, 'pop' it off the stack and write that value to currentValue and 'move' the other value's up.

    There isn't actually a function to 'move' values in an array in Firebase around so just read the array in via code, remove the 0th element and write the array back out.

    I am not a huge fan of Array's in Firebase in general so there are other, more expandable options, but an array may fit this specific use case.