在Firebase Angular2承诺中访问它

时间:2016-12-05 16:55:22

标签: angular typescript firebase firebase-authentication es6-promise

我正在使用Angular2中的Firebase,而我却未能在承诺中访问import { Injectable, Inject } from '@angular/core'; import { AngularFire, AuthProviders, FirebaseAuthState, FirebaseApp } from 'angularfire2'; @Injectable() export class AuthService { user; userUID; userEmail; isAuthenticated: boolean = false; constructor(public af: AngularFire, @Inject(FirebaseApp) firebaseApp: firebase.app.App) { this.af.auth.subscribe(authState => { if (authState && !authState.auth.isAnonymous) { this.user = authState; this.isAuthenticated = true; this.userEmail = this.user.auth.email; this.userUID = this.user.auth.uid; firebaseApp.database().ref('/users/' + this.userUID).once('value').then(function(snapshot) { if (snapshot.val().email !== this.userEmail) { //ERROR HERE console.log('update the email in database here'); } }); console.log('User Logged in', this.user, this.userEmail, this.userUID); return; } this.logout(); console.log('User Not Authenticated', this.user); }); }

这是我的脚本。对于上下文理解:在登录时,我想检查数据库中与该用户相关的基本数据是否仍然是最新的。

if (snapshot.val().email !== this.userEmail)

错误当然是我要进行此比较的行:

#include <iostream>
#include <limits>
#include <typeinfo>

namespace closure {

// A subset of numeric_limits provides, just to shorten stuff.  Tells us all we
// want to know about the properties of a particular integer representation.
template <typename T>
struct repr
{
  static constexpr bool is_signed = std::numeric_limits<T>::is_signed;
  static constexpr int digits = std::numeric_limits<T>::digits;
};

// An estimate of the range of the sum of two integers
template <typename R1, typename R2>
struct add
{
  static constexpr bool is_signed = R1::is_signed | R2::is_signed;
  // Can use std::max() when on C++14 or newer
  static constexpr int digits = ((R1::digits > R2::digits) ? R1::digits : R2::digits) + 1;
};

// Now the mess: map the required number of significant digits back to existing
// types.  Note that the edge case for two's complement is overestimated to
// preserve my personal sanity: e.g., a char covers -128..+127, but we will
// place -128 into an int16_t.
template <int digits, bool is_signed>
struct result_impl;

// Define unsigned types in terms of signed ones
template <int digits> struct result_impl<digits, false>
{
  using type = typename std::make_unsigned<typename result_impl<digits-1, true>::type>::type;
};
template <> struct result_impl<0, false> { using type = uint8_t; };

// Construct the correct type based on the number of needed significant bits.
// binary log
constexpr int log2(int x)
{
  return (x > 1) ? (log2(x>>1)+1) : 0;
}

// The required type based on the binary logarithm of the number of significant bits
template <int logdigits>
struct logtype;

template <> struct logtype<0> { using type = int8_t;  };
template <> struct logtype<1> { using type = int8_t;  };
template <> struct logtype<2> { using type = int8_t;  };
template <> struct logtype<3> { using type = int16_t; };
template <> struct logtype<4> { using type = int32_t; };
template <> struct logtype<5> { using type = int64_t; };

// And this is the actual type for signed integers with a certain minimum number of bits
template <int digits> struct result_impl<digits, true>
{
  using type = typename logtype<log2(digits)>::type;
};

// Finally, our result type using the representation types from above.
template <typename R>
struct result { using type = typename result_impl<R::digits, R::is_signed>::type; };

}

int main()
{
  using namespace closure;

  // Adding two 16-bit values should require a 32-bit type
  std::cout << typeid(result<add<repr<uint16_t>,
                                 repr<uint16_t>>>::type).name() << std::endl;

  // Adding three 16-bit values should still require a 32-bit type
  std::cout << typeid(result<add<add<repr<uint16_t>,
                                     repr<uint16_t>>,
                                 repr<uint16_t>>>::type).name() << std::endl;

  // Adding two 16-bit values, one signed, should require a signed 32-bit type
  std::cout << typeid(result<add<repr<uint16_t>,
                                 repr<int16_t>>>::type).name() << std::endl;

  // Adding a signed 16-bit and an unsigned 32-bit value, should require a signed 64-bit type
  std::cout << typeid(result<add<repr<uint32_t>,
                                 repr<int16_t>>>::type).name() << std::endl;
}

我知道这在JavaScript /打字稿中非常烦人,我无法找到让我的脚本运行的方法。

2 个答案:

答案 0 :(得分:1)

如果您使用箭头功能,它将保留this引用的内容

firebaseApp.database().ref('/users/' + this.userUID).once('value').then((snapshot) => {
    if (snapshot.val().email !== this.userEmail) {
        console.log('update the email in database here');
    }
});

答案 1 :(得分:1)

解决此问题的JavaScript标准技巧是事先将this保存到变量中,然后使用它,通常是let self = this。 在TypeScript中,当您使用胖箭头功能时,该语言会为您执行此操作。已编译的JavaScript代码将具有常规函数,但将在函数内使用名为_this的变量,该变量事先初始化为this,而不是this。 简而言之,请使用function (param) { // code }

,而不是撰写(param) => { // code }