【发布时间】:2018-05-31 21:13:29
【问题描述】:
第一次使用 Firebase 并尝试在 Angular (v5) 应用中设置电子邮件和 Google 身份验证。按照教程 (https://angularfirebase.com/lessons/google-user-auth-with-firestore-custom-data/#Step-5-User-Profile),我得到一个错误:
ERROR TypeError: Cannot read property 'user' of undefined
错误来自模板:
login.component.html
<div *ngIf="auth.user | async; then authenticated else guest">
<!-- template will replace this div -->
</div>
<!-- User NOT logged in -->
<ng-template #guest>
<h3>Howdy, GUEST</h3>
<p>Login to get started...</p>
<button (click)="auth.googleLogin()">
<i class="fa fa-google"></i> Connect Google
</button>
</ng-template>
<!-- User logged in -->
<ng-template #authenticated>
<div *ngIf="auth.user | async as user">
<h3>Howdy, {{ user.displayName }}</h3>
<img [src]="user.photoURL">
<p>UID: {{ user.uid }}</p>
<p>Favorite Color: {{ user?.favoriteColor }} </p>
<button (click)="auth.signOut()">Logout</button>
</div>
</ng-template>
login.component.ts
import {Component} from '@angular/core';
import {AuthService} from '../auth/auth.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent {
constructor(public authService: AuthService) {
}
}
auth.service.ts
import {Injectable} from '@angular/core';
import {Router} from '@angular/router';
import * as firebase from 'firebase/app';
import {AngularFireAuth} from 'angularfire2/auth';
import {AngularFirestore, AngularFirestoreDocument} from
'angularfire2/firestore';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/switchMap'
interface User {
uid: string;
email: string;
photoURL?: string;
displayName?: string;
favoriteColor?: string;
}
@Injectable()
export class AuthService {
user: Observable<User>;
constructor(private afAuth: AngularFireAuth,
private afs: AngularFirestore,
private router: Router) {
//// Get auth data, then get firestore user document || null
this.user = this.afAuth.authState
.switchMap(user => {
if (user) {
return this.afs.doc<User>(`users/${user.uid}`).valueChanges()
} else {
return Observable.of(null)
}
})
}
googleLogin() {
const provider = new firebase.auth.GoogleAuthProvider()
return this.oAuthLogin(provider);
}
private oAuthLogin(provider) {
return this.afAuth.auth.signInWithPopup(provider)
.then((credential) => {
this.updateUserData(credential.user)
})
}
private updateUserData(user) {
// Sets user data to firestore on login
const userRef: AngularFirestoreDocument<any> =
this.afs.doc(`users/${user.uid}`);
const data: User = {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL
};
return userRef.set(data)
}
signOut() {
this.afAuth.auth.signOut().then(() => {
this.router.navigate(['/']);
});
}
}
这个 SO 问题看起来很相似,但不确定答案将如何适用于我的问题:firebase onAuth() throwing: TypeError cannot read property 'auth' of undefined 以及如何解决我的问题。
这是错误的屏幕截图:
【问题讨论】:
-
将
constructor(public authService: AuthService)更改为constructor(public auth: AuthService) -
尝试在所有异步调用中使用 Elvis 运算符... ngIf="auth?.user | async; then authenticated else guest"。这样可以避免很多运行时错误。
-
尝试将你的 html 代码放在你调用 auth.user 的地方,放在
.. 这里访问 auth.user...模板>
标签: angular typescript firebase-authentication