Reputation: 315
I would like to change a location of an element in database. I have tried to firstly remove the element from one location, then push it to another. Here's a method:
firebase.database().ref('completed').on('value', (snapshot) => {
snapshot.forEach((snapchild) => {
if(snapchild.val().title === item.title && snapchild.val().id === item.id) {
firebase.database().ref('todos').push(snapchild.val()).then(() => {
firebase.database().ref(`anotherlocation/${snapchild.key}`).remove()
}
}
})
})
Unfortunately it doesn't work, the element gets deleted but it's not being added to another location. Is it the right way to do it?
Edit: firebase structure added.
Upvotes: 1
Views: 674
Reputation: 599836
There are a few problems with the code:
push
in the new location, which means the item is added with a new key. You'll probably want the item to have the same key in its new location as it had in its old location.id
of the item(s) you want to move, you can limit your read operation to that.In code:
var query = firebase.database().ref('completed').orderByChild('id').equalTo(item.id);
query.on('value', (snapshot) => {
snapshot.forEach((snapchild) => {
if(snapchild.val().title === item.title) {
var updates = {};
updates['/todos/'+snapchild.key] = snapchild.val();
updates['/completed/'+snapchild.key] = null;
firebase.database().ref().update(updates);
}
})
})
This moves the completed item with item.id
back to todos
. I'm not sure if that is the exact move you want to perform, since that wasn't clear from your question. If not, you'll have to update the paths in updates
.
Upvotes: 3
Reputation: 76809
I've once wrote a method, which first creates a copy and then removes the source node. this only would need to be ported from Java
to JavaScript
, which should be a fairly simple task. the order of operations at least is proven to be working. generally, you should replace .on('value')
with .once('value')
, because there won't be any further events - and the deletion should be caught by a ChildEventListener
on the parent node (or however this is called in JavaScript
). if wanting to script this real proper, the encapsulation in a transaction would make sense for the given scenario.
/** relocates a record from one to another path (v2). */
protected void move(final DatabaseReference source, final DatabaseReference target) {
source.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
target.setValue(snapshot.getValue(), new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, @NonNull DatabaseReference databaseReference) {
/* if not the operation has failed */
if (databaseError != null) {
if(mDebug) {Log.w(LOG_TAG, databaseError.getMessage());}
} else {
/* remove the source path */
source.removeValue(new DatabaseReference.CompletionListener(){
@Override
public void onComplete(DatabaseError databaseError, @NonNull DatabaseReference databaseReference) {
if(mDebug) {Log.d(LOG_TAG, "moved " + source.toString() + " to " + target.toString());}
}
});
}
}
});
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
if(mDebug) {Log.w(LOG_TAG, databaseError.getMessage());}
}
});
}
Upvotes: 1