Git Product home page Git Product logo

firebaseextended / emberfire Goto Github PK

View Code? Open in Web Editor NEW
685.0 87.0 264.0 4.52 MB

The officially supported adapter for using Firebase with Ember

Home Page: https://firebaseopensource.com/projects/firebaseextended/emberfire/

License: MIT License

JavaScript 21.35% HTML 2.01% TypeScript 72.55% Shell 0.99% Handlebars 3.11%
firebase javascript ember-data emberjs firebase-sdk realtime-database messaging google-analytics firestore performance-monitoring

emberfire's Introduction

EmberFire Build Status Version Monthly Downloads Ember Observer Score

Status

Status: Experimental

This repository is maintained by Googlers but is not a supported Firebase product. Issues here are answered by maintainers and other community members on GitHub on a best-effort basis.


WARNING: Master branch is the work in progress for version 3 of Emberfire. You can find version 2 here, if you're looking for documentation or to contribute to stable. Learn more about the rewrite effort here.


Why EmberFire?

  • Developed by experts - Developed and maintained by the Firebase team
  • Ember Data Adapters - Cloud Firestore and Realtime Database adapters for Ember Data allow you to persist your models in Firebase
  • Ember Services - firebase and firebase-app services allow direct access to the underlying Firebase SDK instance
  • Realtime Bindings - Listen for realtime updates to your Firebase backed Ember Data models using the provided realtime-listener service or the RealtimeRouteMixin
  • Authentication Providers - Integrate Firebase Authentication with your Ember application easily with providers for Ember Simple Auth and Torii
  • Analytics Collection - The AnalyticsRouteMixin adds Google Analytics screen tracking to your Ember Router.
  • Offline Enabled - Persist Ember Data models offline automatically with FirestoreAdapter
  • Fastboot Compatible - Perform initial rendering and fetching of your models server-side to increase application performance

Installation

$ ember install emberfire@next

Example use

// app/adapters/application.js
import FirestoreAdapter from 'emberfire/adapters/firestore';

export default FirestoreAdapter.extend({
    enablePersistence: true,
    persistenceSettings: { synchronizeTabs: true }
});
// app/models/article.js
import DS from 'ember-data';
const { attr, belongsTo, hasMany } = DS;

export default DS.Model.extend({
    title: attr('string'),
    body: attr('string'),
    publishedAt: attr('date'),
    author: belongsTo('user'),
    comments: hasMany('comments', { subcollection: true }),
});
// app/routes/articles.js
import Route from '@ember/routing/route';
import RealtimeRouteMixin from 'emberfire/mixins/realtime-route';
import PerformanceRouteMixin from 'emberfire/mixins/performance-route';

export default Route.extend(RealtimeRouteMixin, PerformanceRouteMixin, {
    model() {
        return this.store.query('article', { orderBy: 'publishedAt' });
    }
});
// app/routes/application.js
import AnalyticsRouteMixin from 'emberfire/mixins/analytics-route';
import Route from '@ember/routing/route';

export default Route.extend(AnalyticsRouteMixin);

Documentation

Compatibility

Please consult this table when selecting your version of EmberFire and Firebase SDK:

Ember Data EmberFire Firebase SDK
3.0+ 3.x 5.x
2.3+ 2.x 3.x
2.0 - 2.2 1.6.x 2.x
1.13 1.5.x 2.x

Migration Guides

Contributing

If you'd like to contribute to EmberFire, please first read through our contribution guidelines. Local setup instructions are available here.

emberfire's People

Contributors

adjohnson916 avatar anantn avatar aputinski avatar brancusi avatar cohitre avatar dstaley avatar firebase-ops avatar gabrielgrant avatar gpbmike avatar hamzahio avatar jamesdaniels avatar jayphelps avatar knownasilya avatar leifcr avatar m-basov avatar mattmsumner avatar mikkopaderes avatar neverfox avatar olivierchatry avatar oskarrough avatar robtarr avatar rwjblue avatar samtstern avatar sararob avatar stefanpenner avatar steven-ferguson avatar tmayr avatar tomclose avatar tstirrat avatar tsubik 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  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

emberfire's Issues

Loading events

Hi, which loading/success/fail/error events are exposed? Would love a bit more control of the loading states in my app.

Error when calling .destroyRecord()

I asked an SO question about this but this might be an actual issue that needs to be resolved.

I am able to successfully delete a record from Firebase but I get this error every time I do:

Uncaught Error: Attempted to handle event deleteRecord on <App.Organization:ember406:-JJhEoSBi5mBh82n9Y3M> while in state root.deleted.inFlight.

Heres the stack trace:
screen shot 2014-04-07 at 1 21 34 pm

Here is my code:

router.js

App.MainOrgRoute = Ember.Route.extend({
  model: function () {
    return this.store.findAll('organization');
  }
});

models.js

App.Organization = DS.Model.extend({
  name: DS.attr('string')
});

controllers.js

App.MainOrgController = Ember.ArrayController.extend({
  actions: {
    registerOrg: function() {
      var org = this.store.createRecord('organization', {
        'name' : this.get('orgName')
        });
      org.save();

      this.set('orgName', '');
    },
    delete : function(org) {
      this.store.find('organization', org.id).then(function(org) {
        org.destroyRecord();
      });
    }
  }
})

Any ideas?

New record does not remove from store after server delete

I have two models, account and ticket, with the latter linking to the former via a belongTo (with no corresponding hasMany). After creating one of each, displaying them in separate tables (on different routes), I then go into Forge and blow away both records. The account record disappears from my store and app as expected. The ticket, however, sticks around. The store still thinks it's there and it's still displayed in the app. It doesn't matter the order I blow them away either. If I delete the ticket from Firebase, and leave the account, the ticket remains in my store. It also doesn't matter if I remove the belongsTo. To me, this is unexpected behavior.

Adding an existing object to a hasMany association doesn't persist after save()

As an example, let's say we have a Book and a Chapter.

App.Book = DS.Model.extend({
  title: DS.attr('string'),
  chapters: DS.hasMany('chapter')
});

App.Chapter = DS.Model.extend({
  title: DS.attr('string')
});

Calling addObject() on a book.chapters array, providing an existing, non-dirty chapter instance doesn't persist after saving the book. For example,

store.find('book', 1).then(function(book) {
  store.find('chapter', 1).then(function(chapter) {
    book.get('chapters').addObject(chapter);
    book.save();
  });
});

The above code doesn't update the book.chapters object in Firebase.

However, when "dirtying" the chapter object, it persists fine. For example,

store.find('book', 1).then(function(book) {
  store.find('chapter', 1).then(function(chapter) {
    book.get('chapters').addObject(chapter);
    chapter.set('title', 'Updated Chapter Title');  // dirtying the chapter saves the object to book.chapters
    book.save();
  });
});

The above code updates the book.chapters object in Firebase.

Input fields always sends a string for an input field, even when field contents are a number.

So I've got a field bound to an EmberFire object, as specified below:

<label>Page</label>
      {{input type="number" value=model.page classNames="form-control"}}
</div>

I've also got a validate entry on the page field as follows:

"page":{
     ".validate": "newData.isNumber()"
},

I don't have anything special in the controller for the 'page' variable, it just enters it directly into Firebase, and works great if the validate entry isn't in play. However, entry into this field fails, as EmberFire is sending a string of the number, not the actual number.

a question on async: true (not really an issue)

App.Post = DS.Model.extend({ comments: DS.hasMany('comment', { async: true }) }); if I left the {async: true} out App.Post = DS.Model.extend({ comments: DS.hasMany('comment') }); how will the adapter behave? It looks like it will load all comments while fetching the post "at the same time", correct?

Error: No model was was found for '[attribute]'

I'm trying to figure out why my this.store.find('bracket', 'firebase_id').then(func...) is returning Error: No model was found for 'mode'. Mode is an attribute on my bracket model and I can see that it's saved correctly as "team" in my dashboard. I have no idea why it's trying to find a model for mode. It's set as a string attribute in my bracket model.

Just a heads up: I'm using a combination of activemodel adapters and firebase adapters. The tournament model is using an activemodel adapter (which is why I'm not using a simple belongsTo) and the bracket is using a firebase adapter.

Here's what my models look like: https://gist.github.com/JFickel/11130392

I'm pretty confused.

"Error while loading route: undefined " when setting route model hook

I followed the readme to get a basic setup, added a model and then implemented a model hook in a route to return all of the model. This throws the error:

Error while loading route: undefined

I have also tried creating records but they don't seem to get persisted but this may be a separate issue.

I have compiled a minimal jsbin of the problem:

http://emberjs.jsbin.com/kuyujohi/14/edit

App = Ember.Application.create();

App.ApplicationAdapter = DS.FirebaseAdapter.extend({
  firebase: new Firebase('https://emberfire-test.firebaseio.com')
});

App.Post = DS.Model.extend();

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return this.store.find('post');
  }
});

Saving a record with a newly added child updates the view only once.

This example is different to the blog example that's in the repository. I have routes set up like this,

App.Router.map(function() {
  this.resource('posts', function() {
    this.resource('post', {path: ':post_id'}, function() {
      this.resource('comments', function() {
        this.route('new');
      });
    });
  });
});

App.PostsRoute = Ember.Route.extend({
  model: function() {
    return this.store.find('post');
  }
});

App.CommentsRoute = Ember.Route.extend({
  model: function() {
    return this.modelFor('post').get('comments');
  }
});

The post view has a nested comments view which in turn has a nested comments/new view.

When a new comment is created, it's saved and added to the list of comments in the post,

App.CommentsNewController = Ember.ObjectController.extend({
  text: '',
  needs: 'post',
  post: Ember.computed.alias('controllers.post.model'),

  actions: {
    add: function() {
      if (this.get('text')) {
        var newComment = this.store.createRecord('comment', {text: this.get('text')});
        var post = this.get('post');

        post.get('comments').then(function(comments) {
          newComment.save();

          comments.addObject(newComment);
          post.save();
        });

        this.set('text', '');
      }
    }
  }
});

The observed behaviour is that the first time a comment is added after the view is refreshed the view gets updated but any subsequent additions don't update the view although new comments do get persisted.

When the post.save() is taken out, the view gets updated every time you add a comment but because post isn't saved new comments don't get persisted.

Firebase.update throwing error on async property

I've already overridden my FirebaseSerializer to use the updated serializeHasMany method in @neverfox's PR: #51. The embedded ids are now correctly saved after pushing objects into a has many association and saving.

However, I'm running into an error from Firebase.update:

Firebase.update failed: First argument contains undefined in property 'round'

'round' is an async belongsTo association on my match model. I'm not really sure, but my guess is the property is undefined at save time because it's asynchronous. I'll give some context (also, my code in buildRounds seems extremely verbose -- if anyone has suggestions on making things more concise, please let me know):

Bracket = DS.Model.extend({
  tournament_id: attr('number'),
  rounds: DS.hasMany('round', { async: true }),
  mode: attr('string'),
  game: attr('string'),

  build: function(options) {
    if (Ember.isEmpty(options.participants)) {
      return null
    }
    this.set('participants', shuffle(options.participants.content));
    this.set('mode', this.get('participants').get('firstObject').constructor.toString().split('.').get('lastObject').toLowerCase());
    this.set('game', options.game);
    this.set('tournament_id', options.tournament.get('id'));
    this.construct();
  },

  construct: function() {
    this.buildRounds();
    // this.fillFilterRound();
    // this.fillFilteredRound();
    this.save()
  },

  roundCount: function() {
    var roundCountApproximation = Math.log(this.get('participants').length) / Math.log(2);
    return Math.ceil(roundCountApproximation);
  },

  buildRounds: function() {
    var thisBracket = this,
        winnerRound = this.store.createRecord('round', { index: this.roundCount(), bracket: this }),
        winnerMatch = this.store.createRecord('match', { round: winnerRound, index: this.roundCount()  }),
        winnerMatchup = this.store.createRecord('matchup', { top: true, match: winnerMatch }),
        roundCount =  this.roundCount(),
        round,
        builtRounds = [],
        roundIndex,
        matches;

    winnerMatchup.save()

    thisBracket.get('rounds').then(function(rounds) {
      rounds.pushObject(winnerRound);
      thisBracket.save();
    });

    winnerRound.get('matches').then(function(matches) {
      matches.pushObject(winnerMatch);
      winnerRound.save();
    });

    winnerMatch.get('matchups').then(function(matchups) {
      matchups.pushObject(winnerMatchup);
      winnerMatch.save();
    });

    // for (var reverseIndex = 0; reverseIndex < roundCount; reverseIndex++) {
    //   roundIndex = roundCount - reverseIndex - 1;
    //   round = this.store.createRecord('round', { index: roundIndex, bracket: this });
    //   builtRounds.pushObject(round)
    //   round.save()
    //   this.buildMatches(reverseIndex, round);
    // }
    //

  }
  // ....
})

Round = DS.Model.extend({
  index: attr('number'),
  bracket: DS.belongsTo('bracket', { async: true }),
  matches: DS.hasMany('match', { async: true })
})

Match = DS.Model.extend({
  index: attr('number'),
  round: DS.belongsTo('round', { async: true }),
  matchups: DS.hasMany('matchup', { async: true }),
  nextMatchupId: attr('string')
})

Matchup = DS.Model.extend({
  match: DS.belongsTo('match', { async: true }),
  userId: attr('string'),
  teamId: attr('string'),
  top: attr('boolean'),
  origin: attr('boolean')
})

Don't mind the matchup userId/teamId. I'm using a combination of activemodel adapters and firebase adapters.

Aside from seeing the first argument contains undefined in property in 'round' error, everything saves correctly in my use case. It would be nice to see the error go away, though.

Defining properties on your model class breaks the link to Firebase

When model classes are defined in Ember, its properties are listed with their initial values:

App.User = EmberFire.Object.extend({
  username: '',
  votesLeft: 10
})

Since emberFire relies on missing property lookups on the model object (EmberFire.Object) to be proxied to Firebase, if one defines the properties thusly, emberFire will stop working because the property lookups do not get propagated to Firebase.

I'm not sure how much of a problem this is. I'm sure this will bite several Ember devs when starting to use Firebase and I also think the above definition of properties is pretty handy to see what properties a model class has.

I jotted this down to hear your opinion and to see if there is a way around this.

Allow embedded relationships

Not Embedded

Firebase snapshot

{
  "comments": {
    "comment_1": true,
    "comment_2": true
  }
}

Ember Model

App.Post = DS.Model.extend({
  comments: DS.hasMany('comment', { async: true })
});

Embedded

Firebase snapshot

{
  "comments": {
    "comment_1": {
      "body": "Comment number one"
    },
    "comment_2": {
      "body": "Comment number two"
    }
  }
}

Ember Model

App.Post = DS.Model.extend({
  comments: DS.hasMany('comment', { embedded: true })
});

Accessing the keys of an EmberFire Array

It would be handy if EmberFire would provide a _key field that contains the ID of the array item.

I've hacked one up, but I'm working in the ObjectArray fork, so I'm not going to commit it. I also have the problem of not actually wanting the _key field to propagate to Firebase.

EmberFire.Array instances coerced into plain objects when edited

Instances coming from an EmberFire.Array are coerced into plain objects when one of their properties is changed through Ember's binding system.

The problem is easy to reproduce. All you need to do is change a property on the model which has been passed automatically to the instance-level route (ex.: /posts/:post_id) by the array-level route (ex.: /posts).

Here's a JSBin showing the problem:

http://jsbin.com/inUROrO/5/edit

-C

New record not showing up until refresh

When I use this.store.createRecord('ticket', <object>), I have to reload before the new ticket (or record, whichever is more correct lingo) shows up. I entered the code exactly as shown in README.md. I am using ember app kit. I am very new to Firebase and EmberFire, and I hope this is not a stupid question.

run-loop nit-picks

Typically code that mutates state that is managed by ember should be wrapped in a run-loop

I believe the following may not:

It seems like a firebase callback to ember-run aware promise utility method would go along way.
the following seems to be a common pattern.

So this current implementation doesn't really harness some really important aspects of ember and it's run-loop

Let me explain, with XHR it is quite common to have many some what infrequent data updates, when an update happens, we push data into the ember bindings update, observers fire, data settles, and then finally if we need to, we update the DOM.

With WebSockets, or other realtime strategies, it is quite common to have bursts of small updates. Unfortunately currently each update in these bursts will cause change propagation's, that may result in many individual DOM updates. Assuming we get 10 updates in a 50ms window, we would get 10 individual run-loop iterations and up to 10 separate DOM mutations. Interestingly, we would be forcing ember to render at rates greater then even 60FPS, which is wasteful.

In addition if these changes are coalesced into a run loop, they may cancel each other out, result in less or no DOM mutations at all.

Now the above scenario may not effect all classes of applications, but it will effect some.

One potential approach is to batch updates from firebase, and flush them to the ember managed code only at some interval. This interval may depend on the application itself and sometimes may not even be applicable.

Load two models in one route

I'm trying to load two models in one route and am not having any luck figuring it out. One route to hold all information to dynamically create a form and the other model is the one in which it will push form submission data to. Here is some of what I have so far:

Router Map

App.Router.map(function() {
    this.route('about');
    this.route('plans');
    this.resource('prices', function() {
        this.resource('price', { path: '/:price_id' });
    });
    this.resource('apply', function() {
        this.resource('getstarted');
        this.resource('addresses');
        this.resource('contacts');
        this.resource('drivers');
        this.resource('equipment');
        this.resource('assign');
    });
});

Route

App.GetstartedRoute = Ember.Route.extend({
    model: function(){
        return Ember.Object.create({
            form: function() {
                return EmberFire.Array.create({
                    ref: new Firebase("https://example.firebaseio.com/apply/getstarted")
                 });
             },
            data: function() {
                return EmberFire.Array.create({
                    ref: new Firebase("https://example2.firebaseio.com/companies/-JAY7n7gXJeVbFCCDJdH/carriers/")
                 });
             },
        });
    }
});

FireBase json at getstarted

{
  "_type" : "object",
  "1" : {
    "type" : "text",
    "placeholder" : "Type it in here...",
    "name" : "carrierName",
    "caption" : "What's the name of your carrier?"
  }
}

The form is created via recursing through the first model, putting the data into a component that generates the form. I'm trying to access data in the first model using something such as:

{{model.form.type}}

But it is not working...

Any ideas?

An Array of Ember.Objects

I'm trying to take an example project and convert it to use emberFire
https://github.com/Ember-Meteor/leaderboard-example/compare/emberfire

My key problem is that I'm using an EmberFire.Array, but I want to observe the properties of individual objects.

player = Ember.Object.create({name: "Ada Lovelace", score:  5})
list = EmberFire.Array.create({ref: firebaseURI})
list.pushObject(player)

This all works fine,
but I want to increment the score;

player.incrementProperty('score', 5);

But these are not Ember.Objects, so I'd have to say;

player.score = player.score + 5;

However, the EmberFire.Array can therefore not observe the change of the object,
and consequently this doesn't actually work.

Would it be possible to instantiate elements of an EmberFire.Array as Ember.Objects?
Or am I missing something?

Allow models to define a custom Firebase path

Currently, DS.FirebaseAdapter follows the DS.RestAdapter convention for url construction:

App.Post will map to https://<my-firebase>.firebaseio.com/posts

It would be nice to allow models to define what Firebase location contains the data for that model type โ€” inspired by Fireplace

App.Post.reopenClass({
  // Optional
  firebasePath: "blog/posts",
  // Optional
  firebaseFindPath: function(id) {
    return "blog/realposts/%@".fmt(id);
  }
});

ObjectProxy suggestion

ref ends up being a reserved word on EmberFire.Object's now it isn't really a big deal, but this does prevent people from having ref as a property on their data model. In ember we have tried to move away from these sorts of reserved words. Let me propose renaming it from ref to _ref, this should mitigate all reasonable collisions.

Clearing an array

I'm new to Ember so this may be a dumb question, but I was trying to modify the chat example to clear the messages array on a button press. Using the clear method like this:

App.IndexController = Ember.ArrayController.extend({
  msg: "",
  from: "Guest" + Math.floor(Math.random() * 100),
  actions: {
    sendMessage: function() {
      this.pushObject({from: this.get("from"), msg: this.get("msg")});
      this.set("msg", null);
    },
    newSession: function() {
      this.clear();
    }
  }
});

results in the following exception:

Uncaught Error: Firebase.child failed: First argument was an invalid path: "undefined". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]" firebase.js:12
Ga firebase.js:12
J.F firebase.js:134
EmberFire.Array.Ember.ArrayProxy.extend.replaceContent emberfire-latest.js:118
n ember.min.js:13
Ember.ArrayProxy.Ember.Object.extend._replace ember.min.js:16
Ember.ArrayProxy.Ember.Object.extend.replace ember.min.js:16
Ember.ArrayProxy.Ember.Object.extend.replaceContent ember.min.js:16
Ember.ArrayProxy.Ember.Object.extend._replace ember.min.js:16
Ember.ArrayProxy.Ember.Object.extend.replace ember.min.js:16
Ember.MutableArray.Ember.Mixin.create.clear ember.min.js:15
App.IndexController.Ember.ArrayController.extend.actions.newSession app.js:20
Ember.ActionHandler.Ember.Mixin.create.send

Adding objects to a hasMany destroys other hasMany associations after save()

Lets say I have the following application

var App = Ember.Application.create();

App.ApplicationAdapter = DS.FirebaseAdapter.extend({
  firebase: new Firebase('https://<my-app>.firebaseio.com')
});

App.User = DS.Model.extend({
  name: DS.attr('string'),
  posts: DS.hasMany('post', { async: true }),
  comments: DS.hasMany('comment', { async: true })
});

App.Post = DS.Model.extend({
  body: DS.attr('string')
});

App.Comment = DS.Model.extend({
  body: DS.attr('string')
});

And add a few posts to a given user (interacting with the Chrome console)

var store = App.__container__.lookup('store:main');

store.find('user', 1).then(function(u) {
  window.user = u
});

post1 = store.createRecord('post', { body: 'Post 1' });
post2 = store.createRecord('post', { body: 'Post 2' });
post3 = store.createRecord('post', { body: 'Post 3' });

user.get('posts').then(function(posts) {
  posts.addObjects([post1, post2, post3]);
  user.save().then(function() {
    post1.save();
    post2.save();
    post3.save();
  })
});

Creates the posts and associates them correctly in Firebase.

However, adding a comment to the user after the posts are saved results in the posts object being removed in Firebase

comment = store.createRecord('comment', { body: 'Comment 1' });

user.get('comments').then(function(comments) {
  comments.addObject(comment);
  user.save().then(function() { // this line destroys the user.posts object
    comment.save();
  })
});

Idiomatic way to filter on nested route?

I'm trying to figure out how to do filtering on child routes with emberfire since the adapter doesn't implement findQuery. I have the following:

  Advisor = DS.Model.extend
    accounts: hasMany "account", async: true
 Account = DS.Model.extend
    advisor: belongsTo "advisor", async: true
  App.Router.map ->
    @resource "advisor",
      path: "/advisor/:advisor_id", ->
        @resource "advisor.accounts",
          path: "/accounts", ->
            @route "new"
 AdvisorAccountsRoute = Ember.Route.extend #/advisor/:advisor_id/accounts
    model: ->
      # TODO: fetch only this advisor's accounts
      @store.findAll "account"

As you can see it currently fetches all the accounts, but what I want is only the accounts for the advisor in question. Am I supposed to pull all of the accounts into my controller and then filter there (setting the controller to also have the model for the advisor so that I can perform the filter)? That seems less than ideal, but I cannot see any other way. What I would be tempted to do in any other case would be:

 AdvisorAccountsRoute = Ember.Route.extend #/advisor/:advisor_id/accounts
    model: ->
      @store.filter "account", (account) ->
        account.get("advisor").then (advisor) =>
          Ember.isEqual advisor, @modelFor "advisor"

This seems like a common enough scenario that I'm hoping someone will be able to provide an example of the most efficient way to do this. Note that it's imperative that the solution guarantee async resolution of all the data from Firebase before the controller starts computing anything.

DS.FirebaseAdapter.extend - Cannot read property 'extend' of undefined

My wee app was working until you bumped it to 2.0.

I get an error at DS.FirebaseAdapter.extend here:

App.ApplicationAdapter = DS.FirebaseAdapter.extend({
  firebase: new Firebase("https://myapp.firebaseio.com/")
});
App.ApplicationSerializer = DS.FirebaseSerializer.extend();

Guidance please :)

Best practice for displaying embedded records

I am currently getting an error when trying to display embedded records like this:

{{#each items}}
  <li>{{title}}</li>
{{/each}}

The error is: You looked up the 'items' relationship on '<model:list::ember432:-JKbC-s23w5_Wy8MvAc0>' but some of the associated records were not loaded. Either make sure they are all loaded together with the parent reco...<omitted>...)

Is there a best practice for a way to display embedded records? I noticed that If I remove the call to adapter._enqueue in extractSingle it works, so this must be a race condition.

createRecord with an existing ID overrides the record

With the data structure in Firebase:

{
  "posts": {
    1: {
      name: 'test'
      comments: {...}
    }
  }
}

Calling post = store.createRecord('post', id: 1, name: 'change'); post.save() will override the data in Firebase for ID 1 with no error. Resulting in:

{
  "posts": {
    1: {
      name: 'change'
    }
  }
}

Stumped on save behavior using belongsTo

I am trying to create a simple relationship between items, units, and conversions. For some reason, when I create the reverse, "belongsTo" on the model, it doesn't save the references.

So I am trying to create a relationship as follows:

Conversion Model

export default DS.Model.extend({
    order: DS.attr('number'),
    quantity: DS.attr('number'),
    unit: DS.belongsTo('unit', { async: true }),
    item: DS.belongsTo('item', { async: true })
})

For some reason if I put the reverse "belongsTo" on the Conversion model, it won't save to the conversions array. If I remove it, it works. Results are below.

Unit Model

export default DS.Model.extend({
    name: DS.attr('string'),
    gramMultiplier: DS.attr('number'),
    conversions: DS.hasMany('conversion', { async: true })
})

Item Model

export default DS.Model.extend({
    name: DS.attr('string'),
    cost: DS.attr('number'),
    conversions: DS.hasMany('conversion', { async: true })
});

Item Index Controller

var Promise = Ember.RSVP.Promise;

export default Ember.ArrayController.extend({
    newItemName:'Straight torture son!',
    unitTypes:null,

    actions: {
        createItem:function(){
            var item = this.store.createRecord('item', {name:this.get('newItemName'), cost:1});
            var conversion = this.store.createRecord('conversion', {item:item, order:0, quantity:1, unit:this.get('unitTypes').objectAt(0)});

            var promiseCollection = [item.save(), conversion.save()];

            this.set('newItemName', '');

            Ember.RSVP.all(promiseCollection).then(function(fulfilled){
                Promise.cast(item.get('conversions')).then(function(conversions){
                    conversions.addObject(conversion);
                    item.save();
                });
            });
        }
    },
});

Firebase - Without belongsTo refs on the Conversion model

{
    -JKxfFa2G9TDkZ5mM-S8: {
        cost: 1,
        conversions: {
            -JKxfFa4MGiZI9P-hQCi: true
        },
        name: "Straight torture son!"
    }
}

Firebase - WITH belongsTo refs on the Conversion model

{
    -JKxa6nDwGVZtzDMNdsd: {
        cost: 1,
        name: "Straight torture son!"
    }
}

Questions

  1. I am going off of the article https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html - Does this pretty much still stand? Is the preferred method to leave dangling references?
  2. Is there a better way to grab a hasMany array to fill? Rather than: Promise.cast(item.get('conversions'))

hasMany support

In the readme, you mention that hasMany support for ember-data is in the queue.

ember-data seems to require that a collection of ids be sent with the requested objects payload. Is this possible with Firebase?

Plans for support?

Does this plan on having any support moving forward, or has all support moved to angular?

Is it bad to put save logic in the model?

I'm wondering if I should try to extract some of the save logic out of the controllers and into the model, especially when there is a lengthy save chain.

What is the preferred route?

Provide a way to get the underlying Firebase reference

In a small application I've built to try out emberFire I set up a callback thusly:

  this.ref.child('votedOn').on('value', function(snapshot) {
  (...)
  });

That works. However, when I change this to

  this.get('votedOn').on('value', function(snapshot) {
  (...)
  });

It throws an error: TypeError: Cannot call method 'on' of undefined

In theory, missing property lookups should just be proxied to the underlying Firebase reference but it seems like in this case it is not.

ps. The code is here

Emberfire saving Firebase data in store to "_data" not "data"

This is probably due to my noobness with Ember and Firebase, but when I log out what my route's model hook gives me, I find that my Firebase data is not saved under data, but in _data. Then to access the context with handlebars I have to do data.first vs just first.

Here are two pics of what I mean:

screen shot 2014-04-10 at 2 36 40 pm

screen shot 2014-04-10 at 2 36 53 pm

Here is my route:

App.MainUsersRoute = Ember.Route.extend({
  model: function () {
    return this.store.findAll('user');
  }
});

In order to each though my data, I have to do:

{{#each}}
    <tr>
        <td>{{data.first}}</td>
        <td>{{data.last}}</td>
    </tr>
{{/each}}

I'm not sure if this is a quirk with Emberfire or EmberData, or if I'm just calling things wrong.

Support for limit(), startsAt(), and endsAt()

It would be great to be able to use Firebase's limit(), startsAt(), and endsAt().

store.find('post', { limit: 10, startsAt: 100 });

This would require findQuery support in emberFire.

Unable to create record once find has been called

Once store.find('type', id) has been called, store.createRecord(type, id) fails with the following error:

Error: Assertion Failed: The id ID has already been used with another record of type App.Type.

I believe this is because dematerializeRecord is never called on the store when the record is not found. Although it seems like the record should not be in the store until find succeeds.

(blog example)multiple comments real time synchronization

Assuming I have a post with ID 123:
I have the post open in firefox, and I also have the same post open in chrome.

When I add a comment for the post in chrome, I was under the assumption that the same post in firefox should show the newly added comment at "almost" real-time, but it does not seem to work at all. I will have to refresh the page to see the newly added comment.

Is this by design or there are more works needed in order to get the hasMany relationship to update/synch properly?

save() on embedded record causes re-render

I have a model structure as following:

var ListModel = DS.Model.extend({
  name: DS.attr('string'),
  items: DS.hasMany('item', { embedded: true })
});

var ItemModel = DS.Model.extend({
  title: DS.attr('string'),
  completed: DS.attr('boolean', { defaultValue: false })
});

To display these items, I have a view with syntax like this:

{{each items}}
  <li>{{input value=title}}</li>
{{/each}}

Changing the value of the input will then change the value of the title of the ItemModel, which is embedded in a ListModel. Now, if I am observing a change on the title and I try to persist that to firebase with ListModel.save(), everything works great. The change is represented on the firebase data set. However, that causes an entire re-render of the {{each}} block which causes the input to lose focus. Is there anyway to call save() without causing a re-render? especially because no values are changing locally, changes should only be pushed up server side.

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.