Itumac
Itumac

Reputation: 645

Can I prevent Firebase set() from overwriting existing data?

If I do this, all is good with my itemRef:

itemRef.child('appreciates').set(newFlag);
itemRef.child('id').set(newId);

other properties of itemRef remain BUT child_changed is called twice

If I do this:

itemRef.set({appreciates:newFlag,id:newId});

child_changed is called only once but my other properties are destroyed. Is there a workaround besides the clumsy one of repopulating the entire reference object?

Thanks,

Tim

Upvotes: 12

Views: 16224

Answers (5)

fionbio
fionbio

Reputation: 3554

You can create a rule that will prevent overwrites if data already exists. Reproduced here from Firebase docs Existing Data vs New Data

// we can write as long as old data or new data does not exist
// in other words, if this is a delete or a create, but not an update
".write": "!data.exists() || !newData.exists()"

Upvotes: 4

Dharmaraj
Dharmaraj

Reputation: 50850

Though you can use update, you can also use set with merge option set to true:

itemRef.set({ appreciates:newFlag, id:newId }, { merge: true });

This will create a new document if it doesn't exists and update the existing if it does.

Upvotes: 2

RamiroIsBack
RamiroIsBack

Reputation: 270

Now .update takes care of it, you can change existing data or add new one without affecting the rest of data you already had there.

In this example, I use this function to set a product as sold, the product has other variables with data and may or may not have sold or sellingTime but it doesn't matter cos if it doesn't exist will create them and if it does, will update the data

var sellingProduct = function(id){
 dataBase.ref('product/'+id).update({
   sold:true,
   sellingTime: Date.now(),

 }).then (function(){
   alert ('your product is flaged as sold')

 }).catch(function(error){
    alert ('problem while flaging to sold '+ error)
 })

}

Upvotes: 2

Michael
Michael

Reputation: 621

I've been trying to do this having a structure like the following:

Firebase gigs database structure

The problem I was having was when running say set on specific fields such as name, description and date all of the other child nodes would then be removed with the following:

return (dispatch) => {
    firebase.database().ref(`/gigs/${uid}`)
        .set({ name, description, date })
        .then(() => {
            dispatch({ type: GIG_SAVE_SUCCESS });
            Actions.home({ type: 'reset' });
        });
};

Leaving only the name, description and date nodes but using the following the specific nodes are updated without removing the other child nodes i.e. members, image etc:

return (dispatch) => {
    var ref = firebase.database().ref(`/gigs/${uid}`);
    ref.child('name').set(name)
    ref.child('description').set(description)
    ref.child('date').set(date)
        .then(() => {
            dispatch({ type: GIG_SAVE_SUCCESS });
            Actions.home({ type: 'reset' });
        });
}; 

Upvotes: 1

Andrew Lee
Andrew Lee

Reputation: 10185

The Firebase update() function will allow you to modify some children of an object while leaving others unchanged. The update function will only trigger one "value" event on other clients for the path being written no matter how many children are changed.

In this example, you could do:

itemRef.update({appreciates:newFlag,id:newId});

Documentation for update() is here.

Upvotes: 18

Related Questions