Guy
Guy

Reputation: 13336

Firebase array item is removed and immediately auto-added back (with AngularFire)

I am trying to remove an item from $firebaseArray (boxes).

The remove funcion:

function remove(boxJson) {
        return boxes.$remove(boxJson);
    }

It works, however it is immediately added back:

enter image description here

This is the method that brings the array:

function getBoxes(screenIndex) {

        var boxesRef = screens
            .child("s-" + screenIndex)
            .child("boxes");

        return $firebaseArray(boxesRef);

    }

I thought perhaps I'm holding multiple references to the firebaseArray and when one deletes, the other adds, but then I thought firebase should handle it, no?

Anyway I'm lost on this, any idea?

UPDATE

When I hack it and delete twice (with a timeout) it seems to work:

function removeForce(screenIndex, boxId) {

        setTimeout(function () {
            API.removeBox(screenIndex, boxId);
        }, 1000);

        return API.removeBox(screenIndex, boxId);
    }

and the API.removeBox:

function removeBox(screenIndex, boxId) {

        var boxRef = screens
            .child("s-" + screenIndex)
            .child("boxes")
            .child(boxId);

        return boxRef.remove();
    }

Upvotes: 1

Views: 945

Answers (4)

Denis L
Denis L

Reputation: 3302

For those, who have the similar issue, but didn't solve it yet.

There are two methods for listening events: .on() and .once(). In my case that was the cause of a problem. I was working on a migration procedure, that should run once

writeRef
    .orderByChild('text_hash')
    .equalTo(addItem.text_hash)
    .on('value', val => { // <-- 
        if (!val.exists()) {
            writeRef.push(addItem)
        }
    });

So the problem was exactly because of .on method. It fires each time after a data manipulation from FB's console.

Changing to .once solved that.

Upvotes: 0

Guy
Guy

Reputation: 13336

Appearantly I was saving the items again after deleting them. Clearly my mistake:

    function removeSelected(boxes) {
        var selectedBoxes = Selector.getSelectedBoxes(boxes);

        angular.forEach(selectedBoxes, function (box) {

            BoxManager.remove(box);

        });

        Selector.clearSelection(boxes, true);
    }

In the clearSelection method I was updating a field on the boxes and saved them again.

Besides the obvious mistake this is a lesson for me on how to work with Firebase. If some part of the system keeps a copy of your deleted item, saving it won't produce a bug but revive the deleted item.

Upvotes: 1

Frank van Puffelen
Frank van Puffelen

Reputation: 600071

The most likely cause is that you have a security rules that disallows the deletion.

When you call boxes.$remove Firebase immediately fires the child_removed event locally, to ensure the UI is updated quickly. It then sends the command to the Firebase servers to check it and update the database.

On the server there is a security rule that disallows this deletion. The servers send a "it failed" response back to the client, which then raises a child_added event to fix the UI.

Upvotes: 1

omarjmh
omarjmh

Reputation: 13896

When you remove something from firebase it is asynchronous. Per the docs the proper way to remove an item is from firebase, using AngularFire is:

var obj = $firebaseObject(ref);
obj.$remove().then(function(ref) {
  // data has been deleted locally and in the database
}, function(error) {
  console.log("Error:", error);
});

$remove() ... Removes the entire object locally and from the database. This method returns a promise that will be fulfilled when the data has been removed from the server. The promise will be resolved with a Firebase reference for the exterminated record.

Link to docs: https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebaseobject-remove

Upvotes: 1

Related Questions