angular - 为什么 Firebase 中的数据会在刷新后立即加载?(角度)
问题描述
我正在建立一个有角度的网站。
该站点包含一个登录页面,在用户登录后,有一个路由到用户的个人资料页面,存储在 Firebase 中的数据应该出现在该页面。
由于某种原因,数据在刷新页面后立即出现在屏幕上。
你知道原因是什么,我该如何解决这个问题?
先感谢您!
这是我认为的相关代码:
profile.component.html:
<h3 *ngFor="let item of user">Welcome back {{item.name}},</h3>
<h4>Your Details:</h4>
<table>
<tbody *ngFor="let item of user">
<div>
<tr>
<th>Name:</th>
<td>{{item.name}}</td>
</tr>
<tr>
<th>Email:</th>
<td>{{item.email}}</td>
</tr>
<tr>
<th>Phone Number:</th>
<td>{{item.phone}}</td>
</tr>
</div>
</tbody>
</table>
profile.component.ts:
import { Component, OnInit } from '@angular/core';
import {CrudService} from '../services/crud.service';
import { AuthService } from '../services/auth.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
user: any;
message = '';
errorMessage = '';
error: {name:string, message:string} = {name:'' , message:''}; //firebase error handle
constructor(public authservice: AuthService, private router: Router,public crudservice:CrudService) { }
ngOnInit(){
if(this.authservice.currentUser != null)//We will make sure the user is logged in
{
this.crudservice.get_userInfo().subscribe(data => {
this.user = data.map(c => {
return {
id: c.payload.doc.id,
name: c.payload.doc.data()['name'],
email: c.payload.doc.data()['email'],
phone: c.payload.doc.data()['phone'],
};
})
console.log(this.user);
});
}
}
}
auth.service.ts:
import { Injectable } from '@angular/core';
import { AngularFireAuth} from '@angular/fire/auth';
import {Router} from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthService {
authState: any =null;
constructor(private afu: AngularFireAuth, private router: Router) {
this.afu.authState.subscribe((auth =>{
this.authState = auth;
}))
}
//get fanctions, to get data from firebase
get isUserAnonymousLoggedIn(): boolean{
return (this.authState !== null) ? this.authState.isAnonymous : false
}
get currentUserId(): string{
return (this.authState !== null) ? this.authState.uid : ''
}
get currentUserName(): string{
return this.authState['email']
}
get currentUser(): any{
return (this.authState !== null) ? this.authState : null;
}
get isUserEmailLoggedIn(): boolean{
if((this.authState !== null) && (!this.isUserAnonymousLoggedIn)){
return true
} else{
return false
}
}
//function in use in login.component.ts
loginWithEmail(email: string, password: string){
return this.afu.signInWithEmailAndPassword(email, password)
.then((user) => {
this.authState = user
}).catch(error=>{
console.log(error)
throw error
})
}
}
crud.service.ts:
import { Injectable } from '@angular/core';
import { from } from 'rxjs';
import {AngularFirestore} from '@angular/fire/firestore';
import { AuthService } from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class CrudService {
constructor(private authservice: AuthService, public fireservices:AngularFirestore) { }
get_userInfo()
{
return this.fireservices.collection('users').doc(this.authservice.currentUserId).collection('user-info').snapshotChanges();
}
}
login.component.ts:
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../services/auth.service';
import {Router} from '@angular/router';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
email="";
password="";
errorMessage = ''; //validation error handle
error: {name:string, message:string} = {name:'' , message:''}; //firebase error handle
constructor(private authservice: AuthService, private router: Router) { }
ngOnInit(): void {
}
login()
{
this.clearErrorMessage();
if(this.validateForm(this.email, this.password))
{
this.authservice.loginWithEmail(this.email, this.password)
.then(() => {
this.router.navigate(['/profile'])
}).catch(_error =>{
this.error = _error
this.router.navigate(['/login'])
})
}
}
clearErrorMessage()
{
this.errorMessage = '';
this.error = {name: '', message:''};
}
validateForm(email, password)
{
.
.
.
.
}
}
解决方案
那是因为订阅首先返回 null 或 undefined。
要解决此问题,您的代码将如下所示:
this.crudservice.get_userInfo().subscribe(data => {
if(data != null && data != undefined) {
this.user = data.map(c => {
return {
id: c.payload.doc.id,
name: c.payload.doc.data()['name'],
email: c.payload.doc.data()['email'],
phone: c.payload.doc.data()['phone'],
};
})
console.log(this.user);
}
}
您还可以在 HTML 页面中添加 ngIf
<div *ngIf="user != null" >
<h3 *ngFor="let item of user">Welcome back {{item.name}},</h3>
<h4>Your Details:</h4>
<table>
<tbody *ngFor="let item of user">
<div>
<tr>
<th>Name:</th>
<td>{{item.name}}</td>
</tr>
<tr>
<th>Email:</th>
<td>{{item.email}}</td>
</tr>
<tr>
<th>Phone Number:</th>
<td>{{item.phone}}</td>
</tr>
</div>
</tbody>
</table>
</div>
更多细节在这里:
推荐阅读
- c - C中的向量结构
- c# - Parallel.ForEach 在 3 个收益返回后挂起?
- python - 通过COM通过python中的多线程进行Outlook
- shiny - 在闪亮上动态添加情节痕迹
- html - 如何在使用 vba 抓取网页后删除引号
- powerpoint - powerpoint 的 plotly 插件,如何嵌入本地图
- css - CSS:如何使用相对位置和多个项目创建下拉菜单
- python-3.x - 将工作代码转换为更面向对象的结构时出错错误:字符串索引必须是整数 Python 3
- google-sheets - 如何将谷歌表格嵌入或链接到文档?
- python - Python: Calling a function that has a delay, without slowing down main loop