简体   繁体   English

关闭一个emberfire / torii会话并注销会抛出permission_denied错误

[英]Closing an emberfire/torii session and logging out throws permission_denied errors

I am using EmberFire with the Torii for sessions. 我正在使用EmberFire和Torii进行会话。 I am getting an odd issue when I log a user out, and the following errors are thrown in the console: 当我将用户注销时,我遇到一个奇怪的问题,并且在控制台中抛出以下错误:

firebase.js:186 Error: permission_denied at /folders/-KKvrk3K_JOHxQWgR1km: Client doesn't have permission to access the desired data.(…)(anonymous function) @ firebase.js:186(anonymous function) @ firebase.js:380Tb @ firebase.js:276uc @ firebase.js:263vc @ firebase.js:262(anonymous function) @ firebase.js:449vh @ firebase.js:434g.wd @ firebase.js:425Ye.wd @ firebase.js:328(anonymous function) @ firebase.js:326vd @ firebase.js:279La.onmessage @ firebase.js:278
firebase.js:186 Error: permission_denied at /folders/-KLFp3zh5QUB7KvMF0HZ: Client doesn't have permission to access the desired data.(…)(anonymous function) @ firebase.js:186(anonymous function) @ firebase.js:380Tb @ firebase.js:276uc @ firebase.js:263vc @ firebase.js:262(anonymous function) @ firebase.js:449vh @ firebase.js:434g.wd @ firebase.js:425Ye.wd @ firebase.js:328(anonymous function) @ firebase.js:326vd @ firebase.js:279La.onmessage @ firebase.js:278
firebase.js:186 Error: permission_denied at /externalApps/-KLF_wKXtzm38EHtuQ_C: Client doesn't have permission to access the desired data.(…)(anonymous function) @ firebase.js:186(anonymous function) @ firebase.js:380Tb @ firebase.js:276uc @ firebase.js:263vc @ firebase.js:262(anonymous function) @ firebase.js:449vh @ firebase.js:434g.wd @ firebase.js:425Ye.wd @ firebase.js:328(anonymous function) @ firebase.js:326vd @ firebase.js:279La.onmessage @ firebase.js:278
firebase.js:186 Error: permission_denied at /users/-KLKUOZRBCIeCj44WMe7: Client doesn't have permission to access the desired data.(…)(anonymous function) @ firebase.js:186(anonymous function) @ firebase.js:380Tb @ firebase.js:276uc @ firebase.js:263vc @ firebase.js:262(anonymous function) @ firebase.js:449vh @ firebase.js:434g.wd @ firebase.js:425Ye.wd @ firebase.js:328(anonymous function) @ firebase.js:326vd @ firebase.js:279La.onmessage @ firebase.js:278
firebase.js:186 Error: permission_denied at /externalApps/-KLIyXUwTSrkCIL4rz7U: Client doesn't have permission to access the desired data.

There are two places where I login a user: 我登录用户有两个地方:

At Registration 在注册

register(data) {
  return this.get('firebaseApp')
    .auth()
    .createUserWithEmailAndPassword(data.email, data.password)
    .then((registeredUser) => {
      const newUser = this.store.createRecord('user', {
        uid: registeredUser.uid,
        firstName: data.firstName,
        lastName: data.lastName,
        email: registeredUser.email
      })
      return newUser.save();
    })
    .then((savedUser) => {
      return this.get('session').fetch().then(() => {
        return savedUser;
      });
    })
    .then((savedUser) => {
      this.replaceWith('dashboard');
    });
}

For an already registered user 对于已注册的用户

login(email, password) {
  const controller = this.controllerFor('index');
  this.get('session').open('firebase', {
    provider: 'password',
    email: email,
    password: password
  })
  .then((/* response */) => {
    controller.set('loginError', undefined);
    this.replaceWith('dashboard');
  })
  .catch((error) => {
    controller.set('loginError', error);
  });
}

And here is the action that logs the user out: 以下是记录用户的操作:

logout() {
  this.get('session').close().then(() => {
    this.store.unloadAll();
    this.replaceWith('index');
  });
}

I had this very same issue about a week ago. 一周前我遇到了同样的问题。 It seems that the way Emberfire implemented there Ember Data extensions do not allow for the use of store.unloadAll() 似乎Emberfire在Ember Data扩展中实现的方式不允许使用store.unloadAll()

I opened an issue here but haven't seen any responses from the team. 在这里开了一个问题但没有看到团队的任何回复。

You can easily work around this issue by unloading the user directly from the store. 您可以通过直接从商店卸载用户轻松解决此问题。 As long as you use the store.unloadRecord(<specificRecord>) or <specificRecord.unload() then everything works fine. 只要你使用store.unloadRecord(<specificRecord>)<specificRecord.unload()那么一切正常。

In your case you could save the user record when logging in or registering a new user and then unload that record on logout. 在您的情况下,您可以在登录或注册新用户时保存用户记录,然后在注销时卸载该记录。 If all of those actions aren't in the same controller, you would probably have to create a service to handle that interaction. 如果所有这些操作都不在同一个控制器中,您可能必须创建一个服务来处理该交互。

Hope that helps 希望有所帮助

After 2 years the error still exists :) So really quick and dirty solution to avoid the errors in the console. 2年后错误仍然存​​在:)所以真的快速和脏的解决方案,以避免控制台中的错误。 Regarding to this comment the "emberfire never stops listening to any record after its loaded". 关于这个评论,“emberfire永远不会停止在加载后收听任何记录”。 So to "disconnect" from the Firebase server we can simply open (I mean full app[=page] reload) the page without any emberdata elements. 因此,为了与Firebase服务器“断开连接”,我们可以简单地打开(我的意思是完整应用程序[= page]重新加载)页面,而不包含任何emberdata元素。 So my solution (whatever palace in the app): 所以我的解决方案(应用程序中的任何宫殿):

actions: {
    signOut: function () {            
        window.location.replace('/login');
    }
}

On login route: 在登录路线上:

beforeModel(){
    if (this.get('session').get('isAuthenticated')) {            
        this.get('session').close()
    }
}

Some information about my setup: 有关我的设置的一些信息:

DEBUG: Ember : 3.1.3 调查:恩伯:3.1.3

DEBUG: Ember Data : 3.1.1 调查:Ember数据:3.1.1

DEBUG: Firebase : 3.9.0 调查:Firebase:3.9.0

DEBUG: EmberFire : 2.0.10 调查:EmberFire:2.0.10

DEBUG: jQuery : 3.3.1 DEBUG:jQuery:3.3.1

Hope this will help to avoid errors on the page. 希望这有助于避免页面上的错误。 Maybe bad idea if app is really big. 如果app真的很大,也许不好主意。

The key to @Paul's answer is: @Paul答案的关键是:

actions: {
  signOut: function () {            
    window.location.replace('/login');
  }
}

If you're using Emberfire and Torii provider, then you'll need to refetch the session to be able to close it. 如果您正在使用Emberfire和Torii提供程序,那么您需要重新获取会话以便能够关闭它。 This is what I'm doing in my sign-out route... 这就是我在sign-out路线上所做的事情......

export default Route.extend({
  session: inject(),
  redirect() {
    get(this, 'session')
      .fetch()
      .then(async () => {
        await get(this, 'session').close();
        this.transitionTo('/sign-in');
      });
  },
  setupController(controller, model) {
    this._super(controller, model);
  }
});

I setup a controller in this route so that I can show a loading spinner while the app is fetching the session. 我在此路由中设置了一个控制器,以便在应用程序获取会话时显示加载微调器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM