我正在使用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 /打字稿中非常烦人,我无法找到让我的脚本运行的方法。
答案 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 }