AngularFire/Firebase - 检查身份验证状态

标签 angular firebase firebase-realtime-database firebase-authentication angularfire

注意:我对这一切都很陌生,请原谅可能显而易见的内容。非常感谢任何帮助:)

我有什么

  • 用于登录和退出的身份验证服务
  • 根据用户 ID 获取项目的相册服务
    • albumList > UserId > albumKey
  • 在我的专辑列表服务中,我查询路径“albumList > userId”
  • 登录后,这一切正常,并且仅返回基于上述匹配查询的结果

问题

  • 如果我将“localhost:4200/albums”的 URL 复制并粘贴到另一个选项卡中,控制台会显示

Uncaught (in promise): TypeError: Cannot read property 'uid' of null

  • 因此,不会加载任何内容,并且不会维护粘贴的网址

问题

  • 我需要在所有组件中添加用户可观察对象吗?
  • 如何确保在加载数据之前检查用户状态?
  • 是否可以仅使用我的 Auth.Service 作为所有其他组件的引用点?

我的身份验证服务

import { Injectable } from '@angular/core';

import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AuthService {
  user: Observable<firebase.User>;


  constructor(
    private firebaseAuth: AngularFireAuth,
    private router: Router) {
    this.user = firebaseAuth.authState;
  }

  login(email: string, password: string) {
    this.firebaseAuth
      .auth
      .signInWithEmailAndPassword(email, password)
      .then(value => {
        console.log('Nice, it worked!');
        console.log(this.firebaseAuth.auth.currentUser.uid);

        this.router.navigate(['/albums'])
      })
      .catch(err => {
        console.log('Something went wrong:', err.message);
      });
  }

  logout() {
    this.firebaseAuth
      .auth
      .signOut();
  }


}

我的专辑列表服务

注意:如果我删除末尾带有用户 ID 的 albumList 查询(注释掉的查询),我可以将 URL 复制并粘贴到新选项卡中,并且 URL 会保留 (url. com/专辑)。但是,任何数据都不会首先通过用户 key 进行过滤。

import { Injectable } from '@angular/core';
import { AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2/database';

import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class ProjectsListService {
  albumList: FirebaseListObservable<any[]>;
  user: Observable<firebase.User>;

  constructor(
    private database: AngularFireDatabase,
    private firebaseAuth: AngularFireAuth) {

    //this.albumList = database.list('/albumList');
    this.albumList = database.list('/albumList/' + this.firebaseAuth.auth.currentUser.uid);
    //console.log(this.firebaseAuth.auth.currentUser.uid);
  }

  getAlbumList() {
    return this.albumList;
    }


}

最佳答案

Questions

  • Do I need to add a user observable in all my components?

是的,您一直在使用异步数据,您需要订阅来自 firebase 的更改

  • How do I ensure that the user state is checked before loading my data?

看来您对 Angular 也比较陌生,一次学习所有内容可能会比较困难。您应该检查 Router tutorial ,更准确地说是module 5 Route Guards

  • Is it possible to just use my Auth.Service as a reference point for all other components?

是的,这完全取决于您,而且这是很常见的事情。

至于类型错误,您正在尝试访问初始化应用程序时不存在的值,因为您是异步获取的,因此您需要订阅authState

import { Injectable } from '@angular/core';
import { AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2/database';

import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class ProjectsListService {
  albumList: FirebaseListObservable<any[]>;
  user: Observable<firebase.User>;

  constructor(
    private database: AngularFireDatabase,
    private firebaseAuth: AngularFireAuth
  ) {
      firebaseAuth.authState.subscribe(user => {
        console.log(user);
        if (user) {
          this.albumList = database.list('/albumList/' + user.uid);
        }
      })
  }

  getAlbumList() {
    return this.albumList;
  }
}

编辑

前面的代码不起作用,因为当您第一次运行应用程序时,albumList是一个空变量,这就是为什么在导航后一切正常,因为之后它已经初始化并且您可以订阅它。

因此,因为您依赖于身份验证状态,所以您应该在组件上订阅 albumList 。为什么?因为如果您的用户由于某种原因注销,您也会隐藏该信息。

因此,您将执行以下操作,而不是在组件上使用 ProjectsListService:

import { Component } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database'

@Component({
  selector: 'your-component',
  template: `<ul><li *ngFor="let album of albumList | async">{{ todo.text }}</li></ul>`
})
export class YOURComponent {
  albumList: FirebaseListObservable<any[]>;

  constructor(
    private fAuth: AngularFireAuth,
    private database: AngularFireDatabase
  ) {
    fAuth.authState.subscribe(user => {
      if (user) {
        this.albumList = database.list('/albumList/' + user.uid);
        return;
      }
      this.albumList = null;
    })
  }
}

关于AngularFire/Firebase - 检查身份验证状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44928646/

相关文章:

javascript - 为什么我无法访问主题上的管道方法?

javascript - 使用 AnalogJS 渲染具有 2 个或更多路由参数的路由?

java - 如何获取组类型数据库中其他用户的Uid?

javascript - Firebase 函数返回空数据对象

java - Firebase onDataChanged 调用了很多次(没有更新),有时使用空值

javascript - 禁用滚动但保持栏可见

angular - 删除Angularjs2中*ngFor和*ngIf的DOM注释

node.js - Firebase问题,无法设置数据

firebase - runTransaction 和 set() 之间的区别

javascript - 无法以 Angular 5 在我的页面中显示我的数组数据?