Search code examples
javascriptfirebasebackfirebackbonefire

Firebase Backfire: model.set() does not sync to Firebase


I'm new to Backbone and Firebase. I'm using Backfire, have a collection:

var UsersCollection = Backbone.Firebase.Collection.extend({
    model: UserModel,
    firebase: new Firebase( "https://xxxxxx.firebaseio.com/users" ),
});

The model itself is not tied to Firebase (was getting "Invalid Firebase reference created" error):

var UserModel = Backbone.Model.extend({
    defaults: function() {
        return {
            email: "[email protected]"
        };
    }
});

In my View, I instantiate the collection, and I get the data okay, and I can add new models to the collection, as follows:

this.allUsers  = new UsersCollection();
...
this.allUsers.add( userData );

Works great, new user records appear on Firebase. However, let's say I now want to grab a given user's model and update its data:

var userRecord = this.allUsers.findWhere( {email: email} );
userRecord.set( {age: age} );

This updates the model locally but the changed model is NOT getting synced to Firebase. I tried userRecord.save(); afterwards but it triggers a "circular reference" error. Per the docs, set() should do it bur clearly something is off :(


Solution

  • The userRecord variable comes back as undefined in this case because the allUsers collection hasn't been populated with data yet. The data is still being downloaded to Firebase when you are calling .findWhere().

    To avoid this, you can listen to the sync event and do all of your actions from there.

    JSBin example.

    allUsers.on('sync', function(collection) {
      // collection is allUsers
      var userRecord = collection.findWhere( {email: '[email protected]'} );
      userRecord.on('change', function(model) {
         console.log('changed', model);
      });
      userRecord.set( {age:4} );
    });
    

    You'll want to ensure your collections are populated before you process any actions on them. The sync event is the recommended way to do this.