当 auth 状态改变时调用 map 运算符内部的方法
call a method inside of the map operator when the auth state changes
我正在 Angular 8 和 Angularfire 中开发 Web 应用程序。
我正在尝试实施 Firebase 身份验证以登录用户,然后在 Firestore 中读取其数据。最后,使用本地 BehaviorSubject
.
保存此数据
import {User} from 'firebase';
export interface FirebaseUser {
readonly uid: string;
readonly email: string;
readonly emailVerified: boolean;
}
export interface IUser {
id?: string;
email: string;
name: string;
gender: string;
}
@Injectable()
export class AuthService {
// To have the user's auth data from Firebase Authentication.
private bsCurrentUserAuth: BehaviorSubject<FirebaseUser> = new BehaviorSubject<FirebaseUser>(null);
readonly currentUserAuth$: Observable<FirebaseUser> = this.bsCurrentUserAuth.asObservable();
// To have the user's document data.
private bsCurrentUser: BehaviorSubject<IUser> = new BehaviorSubject<IUser>(null);
readonly currentUser$: Observable<IUser> = this.bsCurrentUser.asObservable();
private user$: Observable<IUser>;
constructor(
private afAuth: AngularFireAuth,
private afs: AngularFirestore,
) {
// Subscribe to the auth state, then get firestore user document || null
this.user$ = this.afAuth.authState.pipe(
switchMap(user => {
// Logged in
if (user) {
return this.afs.doc<IUser>(`${COLLECTIONS.USERS}/${user.uid}`).snapshotChanges()
.pipe(
map(changes => {
const data = changes.payload.data() as IUser;
const id = changes.payload.id;
const docData = {id, ...data};
this.saveUser(user, docData); // This is not being called.
return docData;
}));
} else {
// Logged out
this.clearAll();
return of(null);
}
})
);
}
// This is not being called.
private saveUser(user: User, userDoc: IUser) {
console.log('saveUser');
this.bsCurrentUserAuth.next(user);
this.bsCurrentUser.next(userDoc);
}
private clearAll() {
this.bsCurrentUserAuth.next(null);
this.bsCurrentUser.next(null);
}
login(email: string, password: string): Promise<UserCredential> {
return this.afAuth.auth.signInWithEmailAndPassword(email, password);
}
}
现在,用户可以登录,但是,我想保存在 BehaviorSubject
中的数据不存在,因为由于某种原因,saveUser()
方法没有被调用。
想法是:
- 登录
- 将来自 Firebase 身份验证的用户身份验证数据保存在
BehaviorSubject
。
- 将用户文档数据保存在
BehaviorSubject
.
我的目标是让这些数据在两个 BehaviorSubject
.
中可用
我没有看到您实际上在哪里订阅了 user$ observable。看看这个,假设您有正确的导入并订阅 user$,它应该可以正常工作。登录和获取用户状态没有耦合,所以我猜你只是缺少订阅位。
import {User} from 'firebase';
export interface FirebaseUser {
readonly uid: string;
readonly email: string;
readonly emailVerified: boolean;
}
export interface IUser {
id?: string;
email: string;
name: string;
gender: string;
}
@Injectable()
export class AuthService {
// To have the user's auth data from Firebase Authentication.
private bsCurrentUserAuth: BehaviorSubject<FirebaseUser> = new BehaviorSubject<FirebaseUser>(null);
readonly currentUserAuth$: Observable<FirebaseUser> = this.bsCurrentUserAuth.asObservable();
// To have the user's document data.
private bsCurrentUser: BehaviorSubject<IUser> = new BehaviorSubject<IUser>(null);
readonly currentUser$: Observable<IUser> = this.bsCurrentUser.asObservable();
private user$: Observable<IUser>;
constructor(
private afAuth: AngularFireAuth,
private afs: AngularFirestore,
) {
// Subscribe to the auth state, then get firestore user document || null
this.user$ = this.afAuth.authState.pipe(
switchMap(user => {
// Logged in
if (user) {
return this.afs.doc<IUser>(`${COLLECTIONS.USERS}/${user.uid}`).snapshotChanges()
.pipe(
map(changes => {
const data = changes.payload.data() as IUser;
const id = changes.payload.id;
const docData = {id, ...data};
this.saveUser(user, docData); // This is not being called.
return docData;
}));
} else {
// Logged out
this.clearAll();
return of(null);
}
})
).subscribe();
//you need to actually subscribe to the user state be sure to also unsubscribe when this is destroyed if not a singleton service
}
// This is not being called.
private saveUser(user: User, userDoc: IUser) {
console.log('saveUser');
this.bsCurrentUserAuth.next(user);
this.bsCurrentUser.next(userDoc);
}
private clearAll() {
this.bsCurrentUserAuth.next(null);
this.bsCurrentUser.next(null);
}
login(email: string, password: string): Promise<UserCredential> {
return this.afAuth.auth.signInWithEmailAndPassword(email, password);
}
}
我正在 Angular 8 和 Angularfire 中开发 Web 应用程序。
我正在尝试实施 Firebase 身份验证以登录用户,然后在 Firestore 中读取其数据。最后,使用本地 BehaviorSubject
.
import {User} from 'firebase';
export interface FirebaseUser {
readonly uid: string;
readonly email: string;
readonly emailVerified: boolean;
}
export interface IUser {
id?: string;
email: string;
name: string;
gender: string;
}
@Injectable()
export class AuthService {
// To have the user's auth data from Firebase Authentication.
private bsCurrentUserAuth: BehaviorSubject<FirebaseUser> = new BehaviorSubject<FirebaseUser>(null);
readonly currentUserAuth$: Observable<FirebaseUser> = this.bsCurrentUserAuth.asObservable();
// To have the user's document data.
private bsCurrentUser: BehaviorSubject<IUser> = new BehaviorSubject<IUser>(null);
readonly currentUser$: Observable<IUser> = this.bsCurrentUser.asObservable();
private user$: Observable<IUser>;
constructor(
private afAuth: AngularFireAuth,
private afs: AngularFirestore,
) {
// Subscribe to the auth state, then get firestore user document || null
this.user$ = this.afAuth.authState.pipe(
switchMap(user => {
// Logged in
if (user) {
return this.afs.doc<IUser>(`${COLLECTIONS.USERS}/${user.uid}`).snapshotChanges()
.pipe(
map(changes => {
const data = changes.payload.data() as IUser;
const id = changes.payload.id;
const docData = {id, ...data};
this.saveUser(user, docData); // This is not being called.
return docData;
}));
} else {
// Logged out
this.clearAll();
return of(null);
}
})
);
}
// This is not being called.
private saveUser(user: User, userDoc: IUser) {
console.log('saveUser');
this.bsCurrentUserAuth.next(user);
this.bsCurrentUser.next(userDoc);
}
private clearAll() {
this.bsCurrentUserAuth.next(null);
this.bsCurrentUser.next(null);
}
login(email: string, password: string): Promise<UserCredential> {
return this.afAuth.auth.signInWithEmailAndPassword(email, password);
}
}
现在,用户可以登录,但是,我想保存在 BehaviorSubject
中的数据不存在,因为由于某种原因,saveUser()
方法没有被调用。
想法是:
- 登录
- 将来自 Firebase 身份验证的用户身份验证数据保存在
BehaviorSubject
。 - 将用户文档数据保存在
BehaviorSubject
.
我的目标是让这些数据在两个 BehaviorSubject
.
我没有看到您实际上在哪里订阅了 user$ observable。看看这个,假设您有正确的导入并订阅 user$,它应该可以正常工作。登录和获取用户状态没有耦合,所以我猜你只是缺少订阅位。
import {User} from 'firebase';
export interface FirebaseUser {
readonly uid: string;
readonly email: string;
readonly emailVerified: boolean;
}
export interface IUser {
id?: string;
email: string;
name: string;
gender: string;
}
@Injectable()
export class AuthService {
// To have the user's auth data from Firebase Authentication.
private bsCurrentUserAuth: BehaviorSubject<FirebaseUser> = new BehaviorSubject<FirebaseUser>(null);
readonly currentUserAuth$: Observable<FirebaseUser> = this.bsCurrentUserAuth.asObservable();
// To have the user's document data.
private bsCurrentUser: BehaviorSubject<IUser> = new BehaviorSubject<IUser>(null);
readonly currentUser$: Observable<IUser> = this.bsCurrentUser.asObservable();
private user$: Observable<IUser>;
constructor(
private afAuth: AngularFireAuth,
private afs: AngularFirestore,
) {
// Subscribe to the auth state, then get firestore user document || null
this.user$ = this.afAuth.authState.pipe(
switchMap(user => {
// Logged in
if (user) {
return this.afs.doc<IUser>(`${COLLECTIONS.USERS}/${user.uid}`).snapshotChanges()
.pipe(
map(changes => {
const data = changes.payload.data() as IUser;
const id = changes.payload.id;
const docData = {id, ...data};
this.saveUser(user, docData); // This is not being called.
return docData;
}));
} else {
// Logged out
this.clearAll();
return of(null);
}
})
).subscribe();
//you need to actually subscribe to the user state be sure to also unsubscribe when this is destroyed if not a singleton service
}
// This is not being called.
private saveUser(user: User, userDoc: IUser) {
console.log('saveUser');
this.bsCurrentUserAuth.next(user);
this.bsCurrentUser.next(userDoc);
}
private clearAll() {
this.bsCurrentUserAuth.next(null);
this.bsCurrentUser.next(null);
}
login(email: string, password: string): Promise<UserCredential> {
return this.afAuth.auth.signInWithEmailAndPassword(email, password);
}
}