Search code examples
ember.jsfirebaseemberfire

FirebaseSerializer for authentication messing with my models


I'm in the process of implementing Facebook Authentication via Ember CLI + Emberfire + Firebase.

My FirebaseSerializer is messing up the entire app right now.

Here's the error I got:

Error while processing route: lists.index

Assertion Failed: A (subclass of DS.Model) record was pushed into the store with the value of todos being '{-JnTd8HfiWnSCMri7zHV: true}', but todos is a hasMany relationship so the value must be an array. You should probably check your data payload or serializer. Error: Assertion Failed: A (subclass of DS.Model) record was pushed into the store with the value of todos being '{-JnTd8HfiWnSCMri7zHV: true}', but todos is a hasMany relationship so the value must be an array. You should probably check your data payload or serializer.

If I click on the debug link, I see:

Ember['default'].Logger.error.apply(this, errorArgs);

Here is my serializer saved under nutella/serializers/app.js:

import DS from 'ember-data';
import Firebase from 'firebase';
import FirebaseAdapter from 'emberfire/adapters/firebase';

export default DS.FirebaseSerializer.extend();

And here's part the code I added for OAuth that may be causing a problem:

import Ember from 'ember';

var session = Ember.Object.extend({
    ref : new Firebase("https://nutella.firebaseio.com"),

    addFirebaseCallback: function() {
        var session = this;

        this.get("ref").onAuth(function(authData) {
            if (authData) {
                session.set("isAuthenticated", true);
            } else {
                session.set("isAuthenticated", false);
            }
        });
    }.on("init"),

    login: function() {
        return new Promise(function(resolve, reject) {
            this.get("ref").authWithOAuthPopup("facebook", function(error, user) {
                if (user) {
                    resolve(user);
                } else {
                    reject(error);
                }
            });
        });
    },

    currentUser: function() {
        return this.get("ref").getAuth();
    }.property("isAuthenticated")
});


export default {
    name: "Session",

    initialize: function (container, app) {
        app.register("session:main", session);
        app.inject("controller", "session", "session:main");
        app.inject("route", "session", "session:main");
    }
};

I would appreciate your help!


Solution

  • To set up the application serializer you should be creating a file at app/serializers/application.js (not app.js). Your app is actually falling back to the default Ember Data serializer.

    Here is the correct code for setting up FirebaseSerializer as the app's default:

    // app/serializers/application.js
    import FirebaseSerializer from 'emberfire/serializers/firebase';
    
    export default FirebaseSerializer.extend();
    

    However this is probably not necessary.

    To get emberfire working you need to use the Firebase adapter. When you activate this adapter it will automatically register the Firebase serializer as the application default (you can delete app/serializers/application.js completely).

    Are you declaring the firebase adapter in app/adapters/application.js? If not, the quickest way to do this is to run the emberfire generator again:

    ember generate emberfire
    

    This will create your app/adapters/application.js:

    import config from '../config/environment';
    import Firebase from 'firebase';
    import FirebaseAdapter from 'emberfire/adapters/firebase';
    
    export default FirebaseAdapter.extend({
      firebase: new Firebase(config.firebase)
    });
    

    It will place an example firebase URL in config/environment.js. Update this to your real URL.

    These initial steps are outlined in the emberfire quickstart docs.