BehaviorSubject возвращает null в моем доме после входа в систему с Firebase и передает данные пользователя. - PullRequest
0 голосов
/ 28 мая 2020

Я делаю веб-приложение в 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

Кажется, моя подписка в DashboardComponent не получает уведомления , или каким-то образом он уведомляется только один раз.

Моя цель - иметь возможность правильно получать данные пользователя в моем компоненте DashboardComponent после входа пользователя в систему, и все данные были сохранены и отправлены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...