2

I'm having an issue with facebook authentication with the torii adapter, the error being: 'The Torii adapter must implement open for a session to be opened'.

I've visited many tutorials, and tried all presented methods, but most of them are usually old ember code and none of them seem to actually work.

Current state: I am able to login, I get the facebook popup and I can authorize.

Using fiddler, I can also see the response from the API containing a JSON response with all credentials from the user I authenticated with. In the firebase console, I can see the authorized user, reset its password, deny access,...

All this leads me to believe that it's 'merely' a front-end issue where I can't seem to establish a proper 'session' to work with.

My end goal would be to pick up the relevant user data and transfer it to my firebase backend as a 'user' entry, allowing for quick registration for site visitors, but I'll be more than glad to have an active session so I can work out the rest on my own.

As a front-end rookie (I normally code C#), Ember may not have been the best choice to get the hang it, but I'm this far now, I'm not about to let it all slide and pick up a different framework.

My code:

config/environment.js

firebase: {
    apiKey: 'xxxxxxx',
    authDomain: 'myappname.firebaseapp.com',
    databaseURL: 'https://myappname.firebaseio.com',
    storageBucket: 'myappname.appspot.com',
    messagingSenderId: '1234567890'
  },

    torii: {
      sessionServiceName: 'session'
    }

torii-adapters/application.js (I've changed this so much, I can't even remember what the original code was, because none of what I change/add/delete here seems to do anything at all.)

import Ember from 'ember';
import ToriiFirebaseAdapter from 'emberfire/torii-adapters/firebase';

export default ToriiFirebaseAdapter.extend({
  firebase: Ember.inject.service(),
});

routes/application.js

import Ember from 'ember';

export default Ember.Route.extend({
    beforeModel: function() {
    return this.get('session').fetch().catch(function() {
    });
  },

  actions:{

    login: function(provider) {
      this.get('session').open('firebase', {
        provider: provider,
      }).then(function(data) {
        console.log(data.currentUser);
      });
    },

    logout: function() {
      this.get('session').close().then(function() {
        this.transitionTo('application');
      }.bind(this));
    }
  }
});

application.hbs

<div class="container">
  {{partial 'navbar'}}
<a {{action "signIn" "facebook"}} class="btn">{{fa-icon "facebook"}}</a>
<a {{action "signIn" "twitter"}} class="btn">{{fa-icon "twitter"}}</a>
<a {{action "signIn" "github"}} class="btn">{{fa-icon "github"}}</a>
<a {{action "signIn" "google"}} class="btn">{{fa-icon "google"}}</a>
  {{outlet}}
</div>

EDIT 1

Above code is giving me alot more errors after restarting ember server. Is this the cause of my troubles ? All the changes that seemingly didn't change a thing, weren't registered until after a server restart ? If that's the case, I may have passed the correct solution about a hundred times already...

EDIT 2

Changed the code to reflect the actual issue. The previous code was screwed beyond measure, but I never realized it because it didn't pick up until after a server restart.

EDIT 3 Found and tried this, to no avail: https://stackoverflow.com/a/32079863/4309050

Community
  • 1
  • 1
Silvio Langereis
  • 487
  • 1
  • 11
  • 20

3 Answers3

2

This is Lorem Ipsum Dolor's answer, but updated for Ember 3.16+


// Inside routes/application.js
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default class ApplicationRoute Route {
  @service session;
    
  async beforeModel() {
    try {
      return this.session.fetch();
    } catch {}
  }
}

Note that in Ember 3.16+, it is not recommended to add actions to your Route. Instead, you can add them to a Controller or Component context:

import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

export default class LoginLogout extends Component {
  @service session;
  @service router;

  @action
  async login(provider)  {
    let data = await this.session.open('firebase', { provider });

    console.log(data.currentUser);
  }

  @action
  async logout() {
    await this.session.close();

    this.router.transitionTo('application');
  }
}

Note the addition of the router service. The Router service is the way we interact with routing anywhere in our apps.

import ToriiFirebaseAdapter from 'emberfire/torii-adapters/firebase';
    
export default class MyAdapter extends ToriiFirebaseAdapter {

}
NullVoxPopuli
  • 61,906
  • 73
  • 206
  • 352
  • 1
    tis rare that you find up to date ember code, which makes it tough if youre coming to later versions of ember so kudos. Much appreciated. – Craicerjack Feb 27 '21 at 01:30
1

NOTE: for Ember 3.16+ apps, here is the same code, but with updated syntax / patterns: https://stackoverflow.com/a/62500685/356849

The below is for Ember < 3.16, even though the code would work as 3.16+ as fully backwards compatible, but it's not always fun to write older code.


Try to inject service inside your application route and move the beforeModel outside of the actions hash,

// Inside routes/application.js

export default Ember.Route.extend({
  session: Ember.inject.service(), // (1)

  beforeModel: function() {
    return this.get('session').fetch().catch(function() {});
  },

  actions:{
    login: function(provider) {
      this.get('session').open('firebase', {
        provider: provider,
      }).then(function(data) {
        console.log(data.currentUser);
      });
    },

    logout: function() {
      this.get('session').close().then(function() {
        this.transitionTo('application');
      }.bind(this));
    }
  }
});

I have completed the same thing (Firebase Torii Auth) yesterday, try to follow the guide carefully. The only thing missing from the guide is to inject session service manually.

Still remember the session you declared inside environment.js file? You have to inject it to make it available

session: Ember.inject.service(), // (1) 

https://github.com/firebase/emberfire/blob/master/docs/guide/authentication.md

Inside my ToriiFirebaesAdapter,

import ToriiFirebaseAdapter from 'emberfire/torii-adapters/firebase';

export default ToriiFirebaseAdapter.extend({
});
NullVoxPopuli
  • 61,906
  • 73
  • 206
  • 352
XY L
  • 25,431
  • 14
  • 84
  • 143
  • That approach makes sense. I'll give it a whirl and let you know ! – Silvio Langereis Apr 01 '17 at 12:30
  • To be honest ember simple auth is a better choice for Ember app's Authentication. But you need implement your own adapter. – XY L Apr 01 '17 at 12:32
  • I'm getting the same error, even after injecting the session into application.js. I'm on a different machine and started the authentication code from scratch with an earlier commit, I guess I'll have to write my own adapter with simple auth. It's too bad that documentation is really poor on Ember, I enjoy it nonetheless. – Silvio Langereis Apr 01 '17 at 13:15
  • What's the error? Can you try to `log` your session object inside `beforeModel` hook? What's your front-end dependencies? – XY L Apr 01 '17 at 13:16
  • 'The Torii adapter must implement `open` for a session to be opened'. Same code as above, beforeModel moved out of actions and added the injection – Silvio Langereis Apr 01 '17 at 13:17
  • What's your torii version? – XY L Apr 01 '17 at 13:18
  • "emberfire": "2.0.6", "torii": "0.8.2" – Silvio Langereis Apr 01 '17 at 13:18
  • Have you ever install `ember-simple-auth` before? – XY L Apr 01 '17 at 13:19
  • I have, but not on this machine and not inside the commit I started from. – Silvio Langereis Apr 01 '17 at 13:20
  • Give me few mins let me create a fresh demo to see if it works – XY L Apr 01 '17 at 13:31
  • Check out this demo https://github.com/li-xinyang/FE_FirebaseAuthDemo I am using GitHub as the provider and it is working just as expected – XY L Apr 01 '17 at 13:41
  • The code is identical, aside from an ember inject that I removed from 'torii-adapter/application.js', but it still doesn't work. Gonna setup a new app like you did and check if it works. Is it me, or is this rather strange ? – Silvio Langereis Apr 01 '17 at 13:50
  • Do sure why it is not woking for you :`( – XY L Apr 01 '17 at 13:52
  • Same error, started from scratch this time. The only difference is: when using github, I get an 'undefined' error, probably stemming from 'console.log(data.currentUser)' that isn't found. Facebook and twitter auth both give the 'The Torii adapter must implement open for a session to be opened' error. – Silvio Langereis Apr 01 '17 at 14:08
1

I had the same issue and I noticed that my torii-adapters/application.js located under the pods structure (because I use it). So I moved the torii-adapters folder to app folder and everything started to work.

  • Not the case in my project, no pod structure, but the classic layout. I haven't revisited the issue yet, I switched to Auth0, which worked like a charm, out of the box. :) – Silvio Langereis Sep 26 '17 at 09:17