Выход из Firebase генерирует страницу входа - PullRequest
0 голосов
/ 19 января 2019

У меня есть проект Angular 6, в котором я пытаюсь добавить функцию входа / выхода из системы с помощью Firebase.Вот мой код:

isLoggedIn = false;

constructor(private afAuth: AngularFireAuth) {
  this.uid = this.afAuth.authState.pipe(
    map(authState => {
     if (!authState) {
       return null;
     } else {
       this.isLoggedIn = true;
       return authState.uid;
     }
   }),
  );
}

login() {
  try {
    this.afAuth.auth.signInWithPopup(new auth.GoogleAuthProvider()).then(() => {
      this.isLoggedIn = true;
      console.log(1234, this.isLoggedIn);
    });
  } catch (e) {
      console.log(e.message);
  }
}

logout() {
  try {
    this.afAuth.auth.signOut().then(() => {
      this.isLoggedIn = false;
      console.log(4321, this.isLoggedIn);
    });
  } catch (e) {
      console.log(e.message);
  }
}

<button *ngIf="isLoggedIn" class="btn btn-danger" type="button" (click)="logout()">Log Out</button>
<button *ngIf="!isLoggedIn" class="btn btn-danger" type="button" (click)="login()">Log In</button>

Моя проблема в том, что, когда я нажимаю кнопку выхода из системы, кажется, что пользователь выходит из системы, так как появляется кнопка входа в систему, но затем открывается новое окно входа в систему.Что я делаю неправильно.Если у вас есть какие-либо вопросы, не стесняйтесь комментировать, потому что я очень отзывчивый.

1 Ответ

0 голосов
/ 19 января 2019

(Это весь рабочий код?) Помимо пользовательского сценария, когда происходит двойной щелчок (выход из системы и немедленный вход в систему), я не вижу ничего, что могло бы инициировать повторный вход в систему.

Вместо этоговручную установив «isLoggedIn» в ваших методах входа / выхода, вы можете оставаться подписанным на authState для этого (подписка в вашем конструкторе уже делает большую часть этого, это должен быть ngOnInit).Использование authState для управления приводом является хорошей идеей, поскольку в случае сбоя входа или выхода из системы переменная isLoggedIn не будет синхронизирована с действительным authState.

ngOnInit() {
    this.afAuth.authState.pipe(
        tap((user: User | null) =>
            this.isLoggedIn = user !== null
        ),
    ).subscribe();
    // either store the subscription and unsubscribe in destroy,
    // or implement something like takeUntil and the subject to cancel on destroy
}

Если вы чувствуете, что пользовательский интерфейсменяется слишком быстро, вы можете добавить состояние загрузки, возможно, с принудительной задержкой, чтобы было понятно, что делает пользовательский интерфейс.В приведенном ниже примере пользовательское действие используется для установки состояния загрузки (в ожидании чего-то происходящего), а подписка на состояние auth обновляет «isLoggedIn», а затем принудительно устанавливает задержку перед установкой состояния загрузки обратно на «ложь».

loadingSubject = new BehaviorSubject<boolean>(false);
loading$ = this.loadingSubject.asObservable();

isLoggedIn = false;

constructor(private afAuth: AngularFireAuth) {}

ngOnInit() {
    this.afAuth.authState.pipe(
        tap((user: User | null) =>
            this.isLoggedIn = user !== null
        ),
        delay(300),
        tap(() =>
            this.loadingSubject.next(false)
        ),
    ).subscribe();
    // either store the subscription and unsubscribe in destroy,
    // or implement something like takeUntil and the subject to cancel on destroy
}

login() {
    this.loadingSubject.next(true);
    this.afAuth.auth.signInWithPopup(new auth.GoogleAuthProvider());
}

logout() {
    this.loadingSubject.next(true);
    this.afAuth.auth.signOut();
}



<mat-progress-spinner *ngIf="loading$ | async; else buttons" [mode]="'indeterminate'"></mat-progress-spinner>

<ng-template #buttons>
    <button *ngIf="isLoggedIn" class="btn btn-danger" type="button" (click)="logout()">Log Out</button>
    <button *ngIf="!isLoggedIn" class="btn btn-danger" type="button" (click)="login()">Log In</button>
</ng-template>

...