Coder Social home page Coder Social logo

backbonefire's Introduction

Status: Archived

This repository has been archived and is no longer maintained.

status: inactive

BackboneFire

Build Status Coverage Status Version

BackboneFire is the officially supported Backbone binding for Firebase data. The bindings let you use special model and collection types that allow for synchronizing data with Firebase.

Live Demo

Play around with our realtime Todo App demo. This Todo App is a simple port of the TodoMVC app using BackboneFire.

Basic Usage

Using BackboneFire collections and models is very similar to the regular ones in Backbone. To setup with BackboneFire use Backbone.Firebase rather than just Backbone.

Note: A Backbone.Firebase.Model should not be used with a Backbone.Firebase.Collection. Use a regular Backbone.Model with a Backbone.Firebase.Collection.

// This is a plain old Backbone Model
var Todo = Backbone.Model.extend({
  defaults: {
    completed: false,
    title: 'New todo'
  }
});

// This is a Firebase Collection that syncs data from this url
var Todos = Backbone.Firebase.Collection.extend({
  url: 'https://<your-firebase>.firebaseio.com/todos',
  model: Todo
});

Downloading BackboneFire

To get started include Firebase and BackboneFire after the usual Backbone dependencies (jQuery, Underscore, and Backbone).

<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- Underscore -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore.js"></script>

<!-- Backbone -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone.js"></script>

<!-- Firebase -->
<script src="https://cdn.firebase.com/js/client/2.0.3/firebase.js"></script>

<!-- BackboneFire -->
<script src="https://cdn.firebase.com/libs/backbonefire/0.5.1/backbonefire.js"></script>

Use the URL above to download both the minified and non-minified versions of BackboneFire from the Firebase CDN. You can also download them from the releases page of this GitHub repository. Firebase and Backbone can be downloaded directly from their respective websites.

You can also install BackboneFire via Bower and its dependencies will be downloaded automatically:

$ bower install backbonefire --save

Once you've included BackboneFire and its dependencies into your project, you will have access to the Backbone.Firebase.Collection, and Backbone.Firebase.Model objects.

Getting Started with Firebase

BackboneFire requires the Firebase database in order to sync data. You can sign up here for a free account.

autoSync

As of the 0.5 release there are two ways to sync Models and Collections. By specifying the property autoSync to either true of false, you can control whether the component is synced in realtime. The autoSync property is true by default.

autoSync: true

var RealtimeList = Backbone.Firebase.Collection.extend({
  url: 'https://<your-firebase>.firebaseio.com/todos',
  autoSync: true // this is true by default
})
// this collection will immediately begin syncing data
// no call to fetch is required, and any calls to fetch will be ignored
var realtimeList = new RealtimeList();

realtimeList.on('sync', function(collection) {
  console.log('collection is loaded', collection);
});

autoSync: false

// This collection will remain empty until fetch is called
var OnetimeList = Backbone.Firebase.Collection.extend({
  url: 'https://<your-firebase>.firebaseio.com/todos',
  autoSync: false
})
var onetimeList = new OnetimeList();

onetimeList.on('sync', function(collection) {
  console.log('collection is loaded', collection);
});

onetimeList.fetch();

Backbone.Firebase.Collection

This is a special collection object that will automatically synchronize its contents with your Firebase database. You may extend this object, and must provide a Firebase database URL or a Firebase database reference as the url property.

Each model in the collection will have its own firebase property that is its reference in Firebase.

For a simple example of using Backbone.Firebase.Collection see todos.js.

var TodoList = Backbone.Firebase.Collection.extend({
  model: Todo,
  url: 'https://<your-firebase>.firebaseio.com/todos'
});

You may also apply an orderByChild or some other query on a reference and pass it in:

Queries

var TodoList = Backbone.Firebase.Collection.extend({
  url: new Firebase('https://<your-firebase>.firebaseio.com/todos').orderByChild('importance')
});

url as a function

The url property can be set with a function. This function must return a Firebase database ref or a url.

var TodoList = Backbone.Firebase.Collection.extend({
  url: function() {
    return new Firebase(...);
  }
});

initialize function

Any models added to the collection will be synchronized to the provided Firebase database. Any other clients using the Backbone binding will also receive add, remove and changed events on the collection as appropriate.

You should add and remove your models to the collection as you normally would, (via add() and remove()) and remote data will be instantly updated. Subsequently, the same events will fire on all your other clients immediately.

add(model)

Adds a new model to the collection. If autoSync set to true, the newly added model will be synchronized to your Firebase database, triggering an add and sync event both locally and on all other clients. If autoSync is set to false, the add event will only be raised locally.

todoList.add({
  subject: 'Make more coffee',
  importance: 1
});

todoList.on('all', function(event) {
  // if autoSync is true this will log add and sync
  // if autoSync is false this will only log add
  console.log(event);
});

remove(model)

Removes a model from the collection. If autoSync is set to true this model will also be removed from your Firebase database, triggering a remove event both locally and on all other clients. If autoSync is set to false, this model will only trigger a local remove event.

todoList.remove(someModel);

todoList.on('all', function(event) {
  // if autoSync is true this will log remove and sync
  // if autoSync is false this will only log remove
  console.log(event);
});

create(value)

Creates and adds a new model to the collection. The newly created model is returned, along with an id property (uniquely generated by the Firebase client library).

var model = todoList.create({bar: "foo"});
todoList.get(model.id);

todoList.on('all', function(event) {
  // will log add and sync
  console.log(event);
});

Backbone.Firebase.Model

This is a special model object that will automatically synchronize its contents with your Firebase database. You may extend this object, and must provide a Firebase database URL or reference as the url property.

var Todo = Backbone.Firebase.Model.extend({
  url: "https://<your-firebase>.firebaseio.com/mytodo"
});

You may apply query methods as with Backbone.Firebase.Collection.

urlRoot

The urlRoot property can be used to dynamically set the Firebase database reference from the model's id.

var Todo = Backbone.Firebase.Model.extend({
  urlRoot: 'https://<your-firebase>.firebaseio.com/todos'
});

// The url for this todo will be https://<your-firebase>.firebaseio.com/todos/1
var todo = new Todo({
  id: 1
});

You do not need to call any functions that will affect remote data when autoSync is enabled. Calling fetch() will simply fire the sync event.

If autoSync is enabled, you should modify your model as you normally would, (via set() and destroy()) and remote data will be instantly updated.

autoSync: true

var RealtimeModel = Backbone.Firebase.Model.extend({
  url: 'https://<your-firebase>.firebaseio.com/mytodo',
  autoSync: true // true by default
});

var realtimeModel = new RealtimeModel();

realtimeModel.on('sync', function(model) {
  console.log('model loaded', model);
});

// calling .set() will sync the changes to your database
// this will fire the sync, change, and change:name events
realtimeModel.set('name', 'Bob');

autoSync: false

var RealtimeModel = Backbone.Firebase.Model.extend({
  url: 'https://<your-firebase>.firebaseio.com/mytodo',
  autoSync: false
});

var realtimeModel = new RealtimeModel();

realtimeModel.on('sync', function(model) {
  console.log('model loaded', model);
});

// this will fire off the sync event
realtimeModel.fetch();

// calling .save() will sync the changes to your database
// this will fire the sync, change, and change:name events
realtimeModel.save('name', 'Bob');

set(value)

Sets the contents of the model and updates it in your database.

MyTodo.set({foo: "bar"}); // Model is instantly updated in your database (and other clients)

destroy()

Removes the model locally, and from Firebase.

MyTodo.destroy(); // Model is instantly removed from your database (and other clients)

Contributing

If you'd like to contribute to BackboneFire, you'll need to run the following commands to get your environment set up:

$ git clone https://github.com/firebase/backbonefire.git
$ cd backbonefire           # go to the backbonefire directory
$ npm install -g grunt-cli  # globally install grunt task runner
$ npm install -g bower      # globally install Bower package manager
$ npm install               # install local npm build / test dependencies
$ bower install             # install local JavaScript dependencies
$ grunt watch               # watch for source file changes

grunt watch will watch for changes to src/backbonefire.js and lint and minify the source file when a change occurs. The output files - backbonefire.js and backbonefire.min.js - are written to the /dist/ directory.

You can run the test suite via the command line using grunt test.

backbonefire's People

Contributors

abeisgoat avatar aj0strow avatar alexwolfe avatar amir avatar anantn avatar builtbylane avatar costa avatar davideast avatar firebase-ops avatar go-oleg avatar iclems avatar jimrubenstein avatar katowulf avatar lezhangxyz avatar mihar avatar rileydutton avatar robertdimarco avatar samtstern avatar startupandrew avatar stereobit avatar wmdmark avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

backbonefire's Issues

Is this a bug?

I log on the console (using Chrome Dev Tools) the models array of a collection, every time I expand a model's properties I see a 'collection' property, I open, expand models, again the same collection property, tried 10 times same thing. It seems to be a copy of the original collection. Is this a bug on Backfire, Backbone, something else?

Provide Query Support

I would like to be able to use limit(), startAt() etc from Firebase with backfire so I can view a subset of my data.

Trigger an event when an object has reached the server

In some cases it might be useful to know when a particular model has been written to the server (as opposed to just locally), similar to the onComplete callback Firebase provides for push/set. We should expose this in Backfire through an appropriate event on the Collection/Model.

/cc @robv

Backbone.reset() method and event.

This method currently does not exist for Backfire but actually has some needed utility for backbone applications.

Use Case

  1. User has a list of todos in a project
  2. User clicks a Delete All button in the app
  3. All todos in this collection are immediately removed (reset)

This method is also useful for replacing large portions of a collection at once.

The event for this method should also fire once a reset takes place so the app can subscribe to that event as well.

Poor handling of primitive values in backfire collection

If a Firebase node contains children with random keys and primitive values, loading such a collection with backfire breaks, since backfire tries to set an id (the snapshot name) onto each child object, and this is not possible with primitive objects. The objects in the list cannot be removed or changed, since they don't have an ID to match on.

Dynamic Firebase urls

Currently i see no way to specify a dynamic url param to the firebase attribute on a collection.

Its very useful when trying to perform dynamic querying.

Collection.create should return object

It's useful to be able to get a pointer to a newly created object in a collection, especially in live apps. But the Collection.create implementation is really poor for now, considering we should always use add.

You can currently cheat on this by creating the model parameters first like that:

var newObject = { 'title' : 'test' };
collection.add([ newObject ]);
// now newObject has an id !
newObject = collection.get(newObject.id);

In my opinion, this is just exactly what the create method should do, what do you think ?

order: Todos.nextOrder() is brittle

When defining the model, you are using Todos.nextOrder() to set the next order, but that requires that the instantiated collection be named Todos. Would it not be more stable and less brittle if the model were agnostic of its collection's name? It will be in a collection, so simply use 'order: this.collection.nextOrder,' in the model's defaults.

Collection objects should provide a quick access to their fireRef

It would definitely be useful to use Firebase JS tools directly on Backbone model/collections.

Simple example : in a simple chat, I've implemented a "Jason is typing...". If he closes his browser window while typing, I want to remove it from the firebase. Yet, I understand we don't want to replicate everything (even though a simple model.onDisconnect would be perfect), but it's still harder than this as a BackFire Collection creates simple BackBone models with no additional helpers.

It may be nice to have a quick access to the object fireRef to be able at least to do model.fireRef().onDisconnect()...

What do you think ?

Integrity of sequence across clients

Filing this issue on behalf of Tobi:

Sometimes it might be the case that prevChild is not available yet,
locally, so I think I need to determine nearestPrevChild (locally).

So that when I locally have [1,2,3], and get #5, I can position it after
the nearestPrevChild, so that [1,2,3,5]. When I then receive #4, I can
place it after #3 -> [1,2,3,4,5] .

I think that would solve both the case where locally prev child is not
vailable yet, and also the case where the items/messages arrive in
incorrect sequence eg #5 before #4.

If that's true, then I think Backfire should implement that.

model.set should not save data, model.save should handle that

When setting data on a model the data is save instantly. The correct functionality for this would be to only save the data when model.save is called.

Use Case

  1. User edits an item
  2. Edit form appears
  3. Users enters information
  4. Information is set on the model
  5. User clicks cancel
  6. Information is set back to previous attributes
  7. Form is closed and operation is cancelled

In the use case above, the data would have been saved instantly making that change visible for all users even if the user did not intend to save the information yet. For context I've attached a image:

screen shot 2013-09-23 at 3 00 44 pm

Examples not working in Readme.md

I've tried extending from Backbone.Collection as mentioned in readme...turned out it only works with Backbone.Firebase.Collection...

Calling `.fetch()` before firebase has established its connection is a noop.

This is in reference to this style:

Backbone.Collection.extend({
  firebase: new Backbone.Firebase('path to firebase')
})

If you, say during the init of a view, call .fetch() on a collection before Firebase has established it's connection it does nothing. The success function is called like it should be, but none of the data is loaded and no events get fired until another .fetch() is called after Firebase is ready.

I'd expect it to queue things like this and not call the success function until has actually connected and successfully grabbed data.

I can tell it is only after Firebase has established its connection because I can see it do the websocket upgrade in the console. If that happens after my call to .fetch() I get nothing, if it happens before my call to .fetch() everything works as expected.

Can't call model.destroy() on models in a Firebase collection

Given this:

bros = new Backbone.Firebase.Collection
    firebase: 'http://subcultures.firebase.io/bros'

jeff = new Backbone.Model
bros.add jeff

I can do this:

bros.remove jeff

But not this:

jeff.destroy()

For now, I've settled for jeff.collection.remove jeff but that requires my models to know they're in a collection, and I don't like that.

Confusion about localStorage

In https://github.com/firebase/backfire/blob/gh-pages/todos-sync.js#L41 the comment says: "The collection of todos is backed by localStorage instead of a remote server".

I'm a bit confused by that because:

  • I couldn't find any localStorage implementation in backbone-firebase.js
  • I cloned the repo, changed to todos-sync.js in index.html, and tested it locally. It doesn't save anything in localStorage

Am I supposed to implement https://github.com/jeromegn/Backbone.localStorage or something similiar?

Backfire is writing data even when nothing has changed

On receiving data updates from the server, Backfire seems to write the same data back to the server again. This error isn't noticeable unless you have read but not write access to data via security rules, at which point PERMISSION_DENIED errors are logged to the console.

We should add a check to make sure we don't do this. /cc @iclems @mikelehen

Accessing a model object using Backbone.Firebase does not preserve key names

I'm accessing a model like so:

var FirebaseModel = Backbone.Model.extend({
    firebase: new Backbone.Firebase(url)
});

// Instantiate and store the model object.
var model = new FirebaseModel();

// Fetch the model data.
model.fetch({
    success: function() { ... }
});

By the time the fetch success function is called, the model's attributes look like

{
    0: -25200,
    1: "dannibles",
    2: "http://t.co/aMp4KvjuhJ",
    3: "twitter:71932327"
}

instead of

{
    totalPoints: -25200,
    username: "dannibles",
    url: "http://t.co/aMp4KvjuhJ",
    uid: "twitter:71932327"
}

like it should. Thus, there is no way for me to access the models by their key names. However, when I use a firebased-backed collection to retrieve this model object (and all of it's siblings), the model objects have correct keys corresponding to each value.

backfire uncaught error during collection update

Hi guys,
I'm using backfire with require.js for a University project. Everything seems to be working fine but when i update a model inside a collectio from firebase forge i receive inside console this error log:

uncaught error: firebase.update failed: first argument contains undefined in property 'title' at file .../.../.../firebase.js:1

and my local collection inside the app seems not updated...

Collection.add creates new model

Backbone.Firebase.Collection.add() doesn't behave as the Backbone.Collection.add() when adding a model. Instead of adding the model, it creates a new model with the same attributes as the old model. This easily leads to subtle and hard to find bugs when all the bindings on the old model are discarded. The behavior should mimic that of the original Backbone.Collection and if not should be documented as a (IMO) pretty huge caveat.

Backfire embedded references

Hey there

Great work on the bindings. I'm currently attempting to replicate my non-backbone Firebase app in the new bindings. Here's the issue I'm encountering:

My firebase has certain root references. One /messages contains the body of a message, and /inbox has a list of items in this format:

/inbox
-- id: timestamp
-- id: timestamp

/messages
-- id:
-- message: hello
-- user: tom

-- id:
-- message: hello
-- user: tom

... etc

Now this is great and when I create my collection, in this fashion:

    var messageModel = Backbone.Model.extend({});

    var messagesCollection = Backbone.Firebase.Collection.extend({
        model: messageModel,
        firebase: this.userMessagesRef.child(this.user.uid)
    });

I get my list of messages ids back. Now the trouble is as these documents are embedded, or linked, Backbone has no idea how to get them, currently I have to do this in the view:

    // Set up the message item view
    var messageItemView = Backbone.View.extend({
        tagName: 'div',
        template: Handlebars.compile(itemTpl),
        initialize: function() {
            this.listenTo(this.model, 'change', this.render());
        },
        render: function() {
            var selfView = this;

            self.message.messagesRef.child(this.model.get('id')).once('value', function(snapshot) {

                selfView.model.set(snapshot.val(), {silent: true});
                $(selfView.$el)
                        .addClass('message')
                        .data({
                            'id': selfView.model.get('id'),
                            'message': selfView.model.get('message')
                        })
                        .html(selfView.template(selfView.model.toJSON()));
                return selfView;
            });
            return this;
        }
    });

Which completely breaks all of Backbones comparators, and makes it very hard for me to work with the embedded document.

I was hoping that in Backbone.Firebase.Model I could simply initialise it by passing an ID in somewhere but I can't seem to see where to do that - any ideas?

Document that Firebase-backed models shouldn't be added to other Firebase-backed models

If you create a Backbone.Firebase.Collection, and then add another Backbone.Firebase.Collection to it, you'll get an error message, stating that "undefined is not a function" on line 302 of backbone-firebase.js.

I'm pretty sure this behavior isn't allowed, since you'd end up with both models trying to apply updates from Firebase. We should catch this case and throw a helpful error message. We should also document that this isn't allowed.

Another option is to actually support this behavior somehow.

using 'set' with priorities

If you set priority while creating an object and then if you use Method 1 to create a Firebase collection of those objects, now if you try to set a property using, .set on a backbone model in that collection, i get this in the firebug console:

_childMoved called with [object Object]

and all the priorities get screwed up, by that i mean .startAt, .endAt stop working.

THOUGH, The values are set successfully.

Is there something i am missing, or is this a bug?

We need tests

Everybody knows that if you write code without tests, you will be sentenced to

dungeon

`.fetch()` is supposed to return a deferred.

This is in reference to using this style:

Backbone.Collection.extend({
  firebase: new Backbone.Firebase('path to firebase')
})

According to backbone docs (and source), calling .fetch() on a collection or model should return a deferred. Currently the only way around this is using the ability to pass in a success function. It means patterns like using $.when() to synchronize the loading of multiple collections wont work and require you to do your own synchronization.

Document ability to specify firebase property as a function.

When creating a Firebase-backed model, you're allowed to do this:

firebase: function() {
  return new Firebase(...);
}

This is really useful if you want to dynamically configure the location of your Firebase data, but this isn't documented in the readme.

Allow use of queries (limit(), etc) while also allowing writes

I'd really like to be able to use a query as the data source while still being able to write new nodes, in particular for a chat implementation that displays only the K most recent entries.

For example, this fails:

  cls = Backbone.Firebase.Collection.extend(
    model: ChatMessage
    firebase: firebase
      .child('worlds')
      .child(worldId)
      .child('chat')
      .limit(50)
  chatList = new cls()
  chatList.add
    message: 'hello'

I'm not sure how a proper API for the read/write mismatch would look. The workaround is to do this instead:

  ref = firebase
      .child('worlds')
      .child(worldId)
      .child('chat')
  cls = Backbone.Firebase.Collection.extend(
    model: ChatMessage
    firebase: ref.limit(50))
  chatList = new cls()
  ref.push
    message: 'hello'

So it's more of a minor inconvenience than a huge oversight.

Add Support for new Backbone.Firebase.Collection({ ... })

It would be great to be able to define and instantiate a Backbone.Firebase.Collection in the same assignment. For example:

var collection = new Backbone.Firebase.Collection({
    model: Model,

    firebase: new Firebase( 'https://ref.firebaseio.com' )
});

This appears to be unsupported. Instead, something like this must be used:

var Collection = Backbone.Firebase.Collection.extend({
    model: Model,

    firebase: new Firebase( 'https://ref.firebaseio.com' )
});

var collection = new Collection;

No sync, using create on firebase collection

Am I correct in understanding that when I use the firebase collection I lose the sync event (except for on first sync)? If so, this is the exact event that tells me something new I've created was successfully create? Without out it, how do I get an event telling me everything went ok?

The error event does not work either. Both these events work correctly when I use a backbone collection. Should they also work the same with firebase collections?

Provide option to disable auto-syncing of models

A Firebase.Model or Firebase.Collection will automatically start fetching data and syncing any local changes to Firebase. Because of this fetch() and save() have no use in a realtime structure.

A feature to disable sync would be useful for one-time updates.

var Todo = Backbone.Firebase.Model.extend({
  url: 'https://webapi.firebaseio.com/todos/1',
  autosync: false
});

With autosync disabled we then gain the ability to call fetch() and save().

var todo = new Todo();
todo.fetch();
todo.save('title', 'Ice Bucket Challenge');

The same would apply for collections with add() and create().

Add method for getting child model

For a model like:

{
  age: 5,
  name: {first: "John", last: "Doe"}
}

I found having a method like this was useful for creating a model for the nested piece.

var ModelBase = Backbone.Firebase.Model.extend({

  getChildModel: function(name) {
    var child = new ModelBase(null, {firebase: this.firebase.child(name)});
    return child;
  }
});

Could something like this be added to Backbone.Firebase.Model directly?

TypeError: Cannot read property 'c4' of undefined

I've got this collection:

stuff.Collections.Profiles = Backbone.Firebase.Collection.extend({
    firebase: "https://echo.firebaseio.com",
model: stuff.Models.Profile

});

This model:

stuff.Models.Profile = Backbone.Model.extend({
initialize: function() {

    this.set('x',0);
    this.set('y', 0);
}
});

Yet when I do
var profiles = new procrastinate.Collections.Profiles();

I get

TypeError: Cannot read property 'c4' of undefined

or c5, c6, depending. It's the cid of the collection, I know, the internal ID backbone uses because it doesn't have an actual one from the db. I don't know why this is happening.

Can you give me a hand? Thanks.

Jordan

Cannot call model.destroy from within a View w/ Backbone.model

Short Issue:
When a View with a Backbone.Firebase.Collection object calls a series of new View's and passes in a Backbone.model object to them, the model cannot be destroyed within any of the newly created views.

It throws the error:
Uncaught TypeError: Cannot call method 'apply' of undefined backbone-firebase.js:137

It appears that method is set to 'delete' and store[method] is undefined in this context/scope.


Longer Explanation:

Based on @anantn's advice on StackOverflow I've been following the pattern of Views using Backbone.Firebase.Collections which spawn sub-views that have models that extend Backbone.Model to avoid any overlap.

Thus far, this pattern has served me well, but I believe I've found a problem with the Backfire bindings when using this method.

Consider the following scenario: https://github.com/bdickason/shots/blob/12a7682a826d263b3a4b6cab3e802d33ebfc4d6f/app/comments/commentsView.js

commentsView is passed in a Backbone.firebase.collection (commentsCollection) which contains many Backbone.models (commentModel). Comments are displayed in the template with Handlebars' {{each}}

When the 'Delete' functionality takes place within the view, I am able to successfully call this.collection: https://github.com/bdickason/shots/blob/12a7682a826d263b3a4b6cab3e802d33ebfc4d6f/app/comments/commentsView.js#L57

Everything good so far!

This led to some hack-y DOM searches every time I wanted to do anything with a comment (edit, delete, etc), so I migrated them to their own View (commentView): https://github.com/bdickason/shots/blob/1b21124204091c8de4fe03e853944fb84446ef00/app/comments/commentView.js

I iterate through the collection, spawning new commentViews like so:
https://github.com/bdickason/shots/blob/1b21124204091c8de4fe03e853944fb84446ef00/app/comments/commentsView.js#L57

Edit and Save work fine within this new structure, but I get an error when I try to delete (destroy) the current model: https://github.com/bdickason/shots/blob/1b21124204091c8de4fe03e853944fb84446ef00/app/comments/commentView.js#L42

Here's the error description:

Uncaught TypeError: Cannot call method 'apply' of undefined backbone-firebase.js:137
Backbone.Firebase.sync backbone-firebase.js:137
Backbone.sync backbone-firebase.js:165
h.extend.sync backbone.js:284
h.extend.destroy backbone.js:522
module.exports.Backbone.View.extend.deleteComment bundle.js:139
x.event.dispatch jquery.js:4676
x.event.add.y.handle jquery.js:4360

Any help would be appreciated! I'm filing an issue rather than asking a stackoverflow/mailinglist question as I believe this may be a problem with the backfire bindings, but I'm not sure how to fix it :(

Echo Issues

I've been trying to improve it a bit but I'm still only half the way. I've mainly fixed the echo issues for now (as received objects were triggering local changes).

But the issue remains for collections. Even though I prevent any sync from being triggered by the data received, a soon as a sync will happen echoed data will be sent to the server. This means that at the collection level at least, we need to make sure changed attributes only are those who do not the remote values.

Otherwise: it's a huge data loss and a boring issue when you have read-only data (PERMISSION_DENIED all the time then)

Stand Alone Backbone Models

Problem
Often times a backbone applications will have models that are independent from the collection. For example when a user logs into an application there is often times no need to store their data in a collection but rather simply create a backbone model and save and access directly from that model when necessary. The current backfire implementation requires that models are added to collections which are then synced to Firebase.

Use Case

  1. User signs into an application
  2. User data is save to a backbone model
  3. User updates their first name
  4. model.save() is called and user information is save

model.destroy also does not work as a result of this not being stand alone.

collection sync event

The sync event should fire and operate inline with the backbone documentation.

"sync" (model, resp, options) โ€” when a model (or collection) has been successfully synced with the server.

When all of the firebase models have been sync during initialization the collection should fire a single sync event.

Use Case

  1. Application starts up and loading screen is displayed
  2. Content cannot be displayed until all data has been successfully loaded
  3. All items have been downloaded to backbone collection, Sync event is fired.
  4. Loading screen is removed and items are displayed.

This type of functionality is desired when a custom sort function is called on the client side that filters a subset of models from the collection. This can only be done effectively once the entire collection has been loaded otherwise all of the items that match the users query will not be filtered against.

Attaching screen shots for context:
screen shot 2013-09-23 at 3 14 18 pm

screen shot 2013-09-23 at 3 13 32 pm

[enhancement] Add missing bower.json.

Hey, maintainer(s) of firebase/backfire!

We at VersionEye are working hard to keep up the quality of the bower's registry.

We just finished our initial analysis of the quality of the Bower.io registry:

7530 - registered packages, 224 of them doesnt exists anymore;

We analysed 7306 existing packages and 1070 of them don't have bower.json on the master branch ( that's where a Bower client pulls a data ).

Sadly, your library firebase/backfire is one of them.

Can you spare 15 minutes to help us to make Bower better?

Just add a new file bower.json and change attributes.

{
  "name": "firebase/backfire",
  "version": "1.0.0",
  "main": "path/to/main.css",
  "description": "please add it",
  "license": "Eclipse",
  "ignore": [
    ".jshintrc",
    "**/*.txt"
  ],
  "dependencies": {
    "<dependency_name>": "<semantic_version>",
    "<dependency_name>": "<Local_folder>",
    "<dependency_name>": "<package>"
  },
  "devDependencies": {
    "<test-framework-name>": "<version>"
  }
}

Read more about bower.json on the official spefication and nodejs semver library has great examples of proper versioning.

NB! Please validate your bower.json with jsonlint before commiting your updates.

Thank you!

Timo,
twitter: @versioneye
email: [email protected]
VersionEye - no more legacy software!

collection.add() doesn't properly prepare models.

This Collection initializes models with an attribute. Create() works as expected, including the attribute in the object. Add() uses only the passed-in data.

web_inspector__bolzano_local

A non-Firebase-extended collection returns the expected content using add():

web_inspector__bolzano_local

I imagine this is because Backfire create() uses

model = Backbone.Collection.prototype._prepareModel.apply(this, [model, options]);

while add() does not.

It's not clear if the difference is a feature, or an oversight.

Firebase.Collection.prep_for_garbage_collection() needed?

Seems like we could use a little convenience method like the following to render a Firebase.Collection ready for garbage collection:

teardown: ->
    @firebase.off()
    Backbone.Collection.prototype.reset.apply @, [], {silent: true}
    @stopListening()

Any interest in a PR?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.