Я делаю веб-приложение в Angular 8 и Firebase.
При входе пользователя в систему я получаю данные пользователя в Firebase Authentication и Firestore . Затем я сохраняю их в sessionStorage
и отправляю данные в BehaviorSubject
.
Когда пользователь входит в систему, он перенаправляется на мой DashboardComponent , где я подписываюсь на BehaviorSubject
получить его данные и сделать несколько логи c. Проблема в том, что в этот момент BehaviorSubject
возвращает null
.
Service
@Injectable()
export class AuthService {
private storage: Storage = sessionStorage;
private bsCurrentUserAuth: BehaviorSubject<IFirebaseUser> = new BehaviorSubject<IFirebaseUser>(this.userAuth);
readonly currentUserAuth$: Observable<IFirebaseUser> = this.bsCurrentUserAuth.asObservable();
private bsCurrentUser: BehaviorSubject<IUser> = new BehaviorSubject<IUser>(this.userDoc);
readonly currentUser$: Observable<IUser> = this.bsCurrentUser.asObservable();
constructor(
private afAuth: AngularFireAuth,
private afs: AngularFirestore,
) {
// Subscribe to the auth state, then get firestore user document || clearAll
this.afAuth.authState.subscribe(user => {
// Logged in
if (user) {
this.saveUserAuth(user); // Save this in localstorage to get the user's claims.
this.afs.doc<IUser>(`users/${user.uid}`)
.snapshotChanges()
.pipe(
map(changes => {
const data = changes.payload.data() as IUser;
const id = changes.payload.id;
return {id, ...data};
}),
take(1)
).toPromise().then(userDocData => this.saveUserDocData(userDocData)); // Save this in localstorage to get the user's document data.
} else {
// Logged out
this.clearAll();
}
}
);
}
// Save this in localstorage and emit()
private saveUserAuth(user: User) {
this.getUserClaims().then(idTokenResult => {
const userAuth: IFirebaseUser = {
uid: user.uid,
email: user.email,
emailVerified: user.emailVerified,
metadata: user.metadata,
claims: idTokenResult.claims
};
this.bsCurrentUserAuth.next(userAuth);
this.storage.setItem('userAuth', JSON.stringify(userAuth));
});
}
// Save this in localstorage and emit()
private saveUserDocData(userDoc: IUser) {
this.bsCurrentUser.next(userDoc);
this.storage.setItem('userDoc', JSON.stringify(userDoc));
}
/**
* Defined custom attributes on user accounts for role-based access control.
*/
private getUserClaims(): Promise<IdTokenResult> {
return this.afAuth.auth.currentUser.getIdTokenResult();
}
private clearAll() {
this.storage.clear();
this.bsCurrentUserAuth.next(null);
this.bsCurrentUser.next(null);
}
private get userAuth(): IFirebaseUser {
return JSON.parse(this.storage.getItem('userAuth'));
}
private get userDoc(): IUser {
return JSON.parse(this.storage.getItem('userDoc'));
}
}
DashboardComponent
@Component({
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit {
constructor(
private service: AuthService,
) {
}
ngOnInit() {
this.service.currentUser$.subscribe(user => {
// user is null here.
});
}
}
Журналы
![enter image description here](https://i.stack.imgur.com/7DV6F.png)
Кажется, моя подписка в DashboardComponent не получает уведомления , или каким-то образом он уведомляется только один раз.
Моя цель - иметь возможность правильно получать данные пользователя в моем компоненте DashboardComponent после входа пользователя в систему, и все данные были сохранены и отправлены.