kurko / ember-sync

MIT License
282 stars 28 forks source link

emberSync doesn't save to firebase (via EmberFire) #22

Open codepreneur opened 10 years ago

codepreneur commented 10 years ago

So fetching data from firebase works perfectly (with this.emberSync.find('user', '9nj32')), but trying to save to firebase (via EmberFire) doesn't work and the worst part it doesn't throw any errors.

For example:

export default Ember.Route.extend({
    model: function () {
        return this.emberSync.find('user', '2oj9m').then(function(record){
              return user = record;
    });
    },
    actions: {
        save: function () {
            // this.modelFor('index').save();
            // debugger;
            // user.get('name')
            user.save();
            // return user.emberSync.save();
        }
    }
});

with a template:

{{input value=name}}
<button {{action "save"}}>Save</button>

Any ideas? How would you save to firebase?

P.S. I am also using ember localForage adapter

kurko commented 10 years ago

I think your code is wrong.

export default Ember.Route.extend({
  model: function () {
    return this.emberSync.find('user', '2oj9m');
  },

  actions: {
    save: function () {
      // do something cool
      this.get('content').emberSync.save();
    }
  }
});

You need to read Ember.js' guide about what this.get('content') is. I'm closing this, if you have other problems, let us know.

codepreneur commented 10 years ago

If after loading application I do this in the console:

var route = Ember.Namespace.NAMESPACES_BY_ID[''].__container__.lookup('route:index');

I get:

Class {routeName: "index", _names: Array[0], context: Class, currentModel: Class, controller: Class…}

then, when I type this:

var user = route.emberSync.createRecord('user', {name:'kurko'})

I get this:

Class {id: "8tp85", store: Class, container: Container, _changesToSync: Object, _deferredTriggers: Array[0]…}

and then when I type this:

user.emberSync.save()

I get this:

Class {__ember1412872464239: null, __nextSuper: undefined, __ember_meta__: Object, constructor: function, _super: function…}

Then I go to my firebase dashboard and I see that nothing has been added...

However, this: route.emberSync.find('user', '2oj9m') works fine and returns a promise

https://github.com/codepreneur/embersync-localforage-example

csprocket777 commented 9 years ago

@codepreneur did you find a solution to this? I'm running into a similar issue myself.

kurko commented 9 years ago

@codepreneur @csprocket777 I really don't have a way to debug this, but I'll be helping you with whatever I can. Can you perhaps put some debugger; here and there and see what's going on?

Basically, if your Firebase adapter is similar to RESTAdapter/LSAdapter or any Ember compatible adapter, it'll be called according to that interface and it should work. If it works for RESTAdapter and not for Firebase, there's a possibility that your Firebase adapter is broken somehow because nothing is done on EmberSync side, except calling these adapters.

I've been using with ember-json-api (online) and ember-local-storage-adapter (offline) and it works fine.

csprocket777 commented 9 years ago

For the record, here are my versions:

Ember: 1.9.1
Ember-Data: 1.0.0-beta.14
Handlebars: 2.0.0
jQuery: 2.1.3

I'm using the default REST adapter and the LocalStorage Ember-CLI add-on (kurko)

So I've been diving into the code to see if I can pin point where my issue is.

So far I've narrowed it down to a failing promise in ember-sync.js, at this line: https://github.com/kurko/ember-sync/blob/master/dist/ember-sync.js#L448

The console error states:

undefined is not a function

Which is caused by a failure to generate relations, from the function "_this.generateRelationForRecord(type, relation);" here: https://github.com/kurko/ember-sync/blob/master/dist/ember-sync.js#L655

(sorry for the rambling nature, I'm tracing my way through the code)

HERE'S THE CULPRIT At: https://github.com/kurko/ember-sync/blob/master/dist/ember-sync.js#L678 There is a "record.serialize" call, except that in my case, the record is a promise that hasn't been resolved. This is where it fails for me.

I see there is a comment on line 638 to "implement for when .get(relation) returns a Promise". That time might be now. :wink:

In fact, removing the relationships from my model allows the online sync to occur. I'm wondering if there was a change in ember-data to ensure that ALL relationships returned promises by default (maybe they always did and I'm thinking wrong).

Further clarification, I have my "belongsTo" relationship set to async. Removing the async attribute allows the online sync to work as well. It boils down to the need to handle async relationships.

kurko commented 9 years ago

@csprocket777 you rock, sir!

Do you think you can code a PR to implement this? I'll do it myself but I can't guarantee when.

csprocket777 commented 9 years ago

Ugh, I'm not sure how to approach implementing a solution. I'm not sure where to implement a promise to solve for this without breaking the whole thing. I'll play around and see if I can solve for this.

(I know this is alpha and I'm breaking the "don't use it in production yet" rule, but I'm doing it anyways because this solves a huge issue for me right now, and I'm under the gun)

kurko commented 9 years ago

@csprocket777 under the gun? :scream: :gun:

You can hit me up at #emberjs channel on Freenode if you need. If you can at least write a failing spec in a PR, I'll try to make a patch tonight.

kurko commented 9 years ago

@csprocket777 from our conversation on IRC, here's a gist with what I think should be done: https://gist.github.com/kurko/7ca3b17fa6b7590b93a1