I've followed the EmberFire guide to setting up authentication with the torii provider and it works perfectly. I'm looking to store the users data in firebase after the user has been authenticated and to have access to the user object throughout the application.
I have previously done this with ember awhile back but i'm unsure how to do it using the new torii provider.
I'm thinking i should test wether the user is already stored in firebase in an initialiser function and then inject the user into the controllers/routes.
Any help pointing me in the right direction would be helpful or some example code.
Thanks
You need a Torii adapter that implements open
and fetch
and does a find
/save
to your app specific user model. Our ToriiFirebaseAdapter does not do this, yet. I've gone ahead and knocked one up for you that will work:
// app/torii-adapters/application.js
import Ember from 'ember';
export default Ember.Object.extend({
firebase: Ember.inject.service(),
store: Ember.inject.service(),
/**
* Executed after Firebase authentication.
*
* Find or create the user based on the Firebase `authData`
*
* @param {Object} authData
* @return {Promise<Object>} Updated session info
*/
open(authData) {
return this._findOrCreateUser(authData)
.then((user) => {
return { currentUser: user };
});
},
/**
* Fetch an existing Firebase auth session and place into `session.currentUser`
*
* @return {Promise<Object>} Updated session info
*/
fetch() {
let ref = this.get('firebase');
let authData = ref.getAuth();
if (!authData) {
return Ember.RSVP.Promise.reject(new Error('No Firebase session found'));
}
return this._findOrCreateUser(authData)
.then((user) => {
return { currentUser: user };
});
},
/**
* Teardown a session. Remove the `session.currentUser`.
*
* @return {Promise<Object>} Updated session info
*/
close() {
this.get('firebase').unauth();
return Ember.RSVP.Promise.resolve({ currentUser: null });
},
/**
* Find the user with the given `authData`, create if not found
*
* @param {Object} authData
* @return {Promise<Object>} The user
*/
_findOrCreateUser(authData) {
let store = this.get('store');
return store.find('user', authData.uid)
.catch(() => {
let newUser = store.createRecord('user', this.extractUserProperties(authData));
return newUser.save();
});
},
/**
* Extract the user properties from `authData` that you care about.
*
* @param {Object} authData
* @return {Object} An updated property hash
*/
extractUserProperties(authData) {
var name = 'Unknown';
var provider = authData.provider;
var userData = authData[provider];
if (userData.displayName) {
name = userData.displayName;
} else if (userData.username) {
name = userData.username;
}
return {
id: authData.uid,
name: name,
email: userData.email || null
};
}
});
All you need to do is update the extractUserProperties
method to get the properties you care about into their correct place on your user model - everyone implements their user model differently.
Now you should be able to look up session.currentUser
and it will return an Ember Data model that corresponds to the logged in user.
Hope that helps. We are in the process of adding this to the website documentation and will try to find a way to roll this into the EmberFire supplied ToriiFirebaseAdapter.