无需使用观察者即可将用户详细信息存储在本地存储中(Firebase& Polymer身份验证)

时间:2016-11-23 16:33:28

标签: firebase polymer firebase-authentication polymer-1.0

我用Polymer& amp;创建了一个简单的登录Firebase(谷歌身份验证)。我遇到了一个让我觉得我选择的方法可能不是最干净的问题。所以这个问题更多的是关于一般模式 在下面的代码中,我结合了最新Polycast video的基本登录信息和我在Firebase Guide中找到的一些代码。

问题
基本上我无法调用登录中的一个函数然后存储值,也不能直接在登录方法中存储返回的用户值。

我的解决方案
为了解决这个问题,我创建了一个监听器,如果用户存在则触发该监听器,然后调用modify方法将用户详细信息存储在localstorgae userDetails对象中。

所以我想知道我的方法是否是okey以及我可以改进以跳过观察者并将用户详细信息存储在login方法中。另外,我在Firebase指南中找到了一个特殊的观察者,但不知道如何实现它。

<dom-module id="my-app">
 <template>
  <style>
   :host {
    display: block;
   }
  </style>

  <firebase-app auth-domain="...firebaseapp.com"
    database-url="...firebaseio.com"
    api-key="..."></firebase-app>

  <iron-localstorage id="localstorage" name="my-app-storage"
    value="{{userDetails}}"></iron-localstorage>

  <section class="wrapper">
    <paper-material id="loginContainer" elevation="1">
    <firebase-auth id="auth"
      user="{{user}}"
      status-known="{{statusKnown}}"
      provider="{{provider}}"
      on-error="handleError"></firebase-auth>

    <template is="dom-if" if="[[user]]">
      <h1>Welcome [[user.displayName]]</h1> 
    </template> 

    <paper-button raised on-tap="login" hidden$="[[user]]">Sign in</paper-button> 
    <paper-button raised on-tap="logout" hidden$="[[!user]]">Sign out</paper-button>  
  </paper-material>
</section>

</template>
<script>
  Polymer({
    is: 'my-app',

    properties: {
      userDetails: {
        type: Object,
      },
      user: {
        type: Object,
        observer: '_changed'
      },
      statusKnown: {
        type: Object
      },
      provider: {
        type: String,
        value: 'google'
      }
    },

    login: function() {
      this.$.auth.signInWithPopup(this.provider).then(function(result) {
      var token = result.credential.accessToken;
      // The signed-in user info.
      var user = result.user;

      //UNABLE TO CALL A METHOD OR TO STORE VALUES DIRECTLY IN MY OBJECT


      }).catch(function(error) {
        // Handle Errors here.
        var errorCode = error.code;
        var errorMessage = error.message;
        var email = error.email;
        var credential = error.credential;
      });
    },
    //OBSERVER THAT CALLS THE MODIFICATION FOR THE LOCALSTORAGE
    _changed: function() {
      if (this.user != null) {
        var user = firebase.auth().currentUser;
        this.makeModifications(user);
      }
    },
    // set localstorage
    makeModifications: function(user) {
      this.set('userDetails.name', user.displayName);
      this.set('userDetails.email', user.email);
      this.set('userDetails.photoUrl', user.photoURL);
      console.log(this.userDetails.name + ' is singed in');
    },
    logout: function() {
      this.$.localstorage.reload();
      this.set('userDetails.name', null);
      this.set('userDetails.email', null);
      this.set('userDetails.photoUrl', null);
      return this.$.auth.signOut();
    },

  });
 </script>
 </dom-module>

1 个答案:

答案 0 :(得分:1)

你的范围有问题吗?当在这里。$。auth.signInWithPopup()。然后(函数你不能使用Polymers this.set,因为你在一个新的范围内。你所做的事情也没有错,asuming它的作品适合你。

this.$.auth.signInWithPopup().then(function(user) {
  // notice bind(this), binds your polymer element to the scope of the 
  // function, this allows you to use its API, thus enabling
  // the use of set within the Promise
  this.set('userDetails.name', user.displayName);
}.bind(this));

这也可以通过

完成
login: function() {
  // create a local reference to the Polymer element
  // assuming its within a closure like this login function it will be 
  // available to any function called from it.
  var that = this; 
  this.$.auth.signInWithPopup().then(function(result) {
    var user = result.user
    that.set('userDetails.name', user.displayName);
  });
}

我没有在编写代码时对此代码进行测试,因此请谨慎使用。

Closures Example

我最近这样做的方式是

login: function() {
  this.$.auth.signInWithPopup()
      .then(this._setUserDetails.bind(this))
      .then(this._anotherFunctionCall.bind(this));
},
_setUserDetails: function(user) {
  this.set('userDetails.name', user.displayName);
  return Promise.resolve();
}

它没有做任何额外的事情只是感觉更清洁