Q:

Firebase Atmonic Add and delete entry

I have the following data structure in my firebase
-ActionSheet
    -PendingApproval 
        -SomeKey1
            -someData
            -someData
            -someData
        -SomeKey2
            -someData
            -someData
            -someData
    -Approved
        -SomeKey3
            -someData
            -someData
            -someData

The user is displayed with all the items in pendingApproval when the screen appears. 
When the user clicks approve on one of the entry, I want to move the data from "PendingApproval" to "Approved" node.
Say if the user clicked approved for SomeKey1, Currently, I am doing it the following way 
1. Duplicate the data to Approved node 

2. Upon success, delete the entry SomeKey1 from PendingApproval 

However, there is a small chance that step one succeeded and step two failed. In this case I would have two SomeKey1 in my database
I was wondering if there is a way to do this atomatically such that the operation is guaranteed to succeed or fail at the same time.
I have just read Firebase Atmoic and they only mentioned atomic update as oppose to "set + remove".
Below is my code
// save data to firebase
saveoFirebase_approved(myData: Object, key: string) {
    let savePath = '/ActionSheet/Approved/' + key;
    return this.af.database.object(savePath).set(myData);
}

// remove pending approval from firebase
removePendingFromFirebase(myData: Object) {
    let savePath = '/ActionSheet/PendingApproval/' + key;
    return this.af.database.object(savePath).remove();
}

this.databaseService.saveoFirebase_approved(data, key)
  .then(result => {

    // delete pending from firebase
    this.databaseService.removePendingFromFirebase(data)
      .then(result => {
        // both action completed
      })
      .catch(error => {
        // something went wrong deleting item from firebase
      })
  })
  .catch(error => {
    // something went wrong saving to firebase
  })
 }

Note: I am using Angular 2 with AngularFire

A:

You can delete data in a multi-location update by setting null to the location. So your operation then becomes:
var updates = {
  'PendingApproval/SomeKey1': null,
  'Approved/SomeKey1': {
    SomeDate: 'Value'
  }
};
ref.child("ActionSheet").update(updates);

You could even validate in your security rules that data can only be written to Approved if it was previously pending and is now no longer pending:
"Approved": {
  "$key": {
    ".write": "data.parent().parent().child('PendingApprocal').child($key).exists()
        && !newData.parent().parent().child('PendingApprocal').child($key).exists()"

