104

As the title says, I can't get the differences between update and set. Also the docs can't help me, as the update example works exactly the same if I use set instead.

The update example from the docs:

function writeNewPost(uid, username, title, body) {

    var postData = {
        author: username,
        uid: uid,
        body: body,
        title: title,
        starCount: 0
    };

    var newPostKey = firebase.database().ref().child('posts').push().key;

    var updates = {};
    updates['/posts/' + newPostKey] = postData;
    updates['/user-posts/' + uid + '/' + newPostKey] = postData;

    return firebase.database().ref().update(updates);
}

The same example using set

function writeNewPost(uid, username, title, body) {

    var postData = {
        author: username,
        uid: uid,
        body: body,
        title: title,
        starCount: 0
    };

    var newPostKey = firebase.database().ref().child('posts').push().key;

    firebase.database().ref().child('/posts/' + newPostKey).set(postData);
    firebase.database().ref().child('/user-posts/' + uid + '/' + newPostKey).set(postData);
}

So maybe the example from the docs should be updated, because now it looks like update and set do the exact same thing.

Kind regards, Bene

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Bene
  • 1,041
  • 2
  • 8
  • 8

1 Answers1

177

Atomicity

One big difference between the two samples you've given is in the number of write operations they send to the Firebase servers.

In the first case, you're sending a single update() command. That entire command will either succeed or fail. For example: if the user has permission to post to /user-posts/' + uid, but doesn't have permission to post to /posts, the entire operation will fail.

In the second case, you're sending two separate commands. With the same permissions, the write to /user-posts/' + uid will now succeed, while the write to /posts will fail.

Partial update vs complete overwrite

Another difference is not immediately visible in this example. But say that you're updating the title and body of an existing post, instead of writing a new post.

If you'd use this code:

firebase.database().ref().child('/posts/' + newPostKey)
        .set({ title: "New title", body: "This is the new body" });

You'd be replacing the entire existing post. So the original uid, author and starCount fields would be gone and there'll just be the new title and body.

If on the other hand you use an update:

firebase.database().ref().child('/posts/' + newPostKey)
        .update({ title: "New title", body: "This is the new body" });

After executing this code, the original uid, author and starCount will still be there as well as the updated title and body.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 15
    Thank you very much for the answer. Maybe it would be a good idea to update the docs with a clearer example for the update method. – Bene Aug 12 '16 at 19:25
  • 8
    @frank-van-puffelen Sounds like `update()` is the goto workhorse that can do it all. You can even `update` properties to be `null`... effectively doing the same job of `remove`. So with that, is there any real good reason to use `set()` at all? Maybe if you want to do some serious trimming/reshaping of data? – jmk2142 Feb 27 '17 at 00:59
  • 6
    The docs certainly need to be improved to add the information from this answer in a clear manner. – Splaktar Apr 28 '17 at 04:50
  • For offline situation, I found that 'set' is efficient as it commits all the changes to firebase database once the client gets online. Whereas 'update' did not commit all the pending changes to the firebase database when the client return to online mode. Please correct me if I am wrong. – Murtuza May 27 '18 at 12:17
  • 1
    is **update** work for creating a new data field too @Frank? – subrata sharma Feb 18 '20 at 08:26
  • 2
    Yes it does. Give it a try, and open a new question if you're having problems making it work for your case. – Frank van Puffelen Feb 18 '20 at 14:09
  • 1
    One major difference is that if you use set on top level while you have children, it will wipe them out if you not careful... – David Constantine May 26 '20 at 07:55