AngularFire根据用户身份验证检索文档ID

标签 angular firebase

我正在 firebase 中设置自定义用户数据库,其中将使用用户身份验证 uid 存储文档 ID。

我目前面临的问题是存储当前用户文档,以便在用户登录时显示在我的仪表板上。

目前,在我的 authService.ts 上,我存储来自 firebase.user 的数据 在我的仪表板上将仅显示默认数组中的信息。 这就是我的 auth.service.ts

中的内容
export class AuthService {
  userData: any; 
  userCollection: AngularFirestoreCollection<User>;
  constructor(

    public afs: AngularFirestore,   // Inject Firestore service
    public afAuth: AngularFireAuth, // Inject Firebase auth service
    public router: Router,  
    public ngZone: NgZone, // NgZone service to remove outside scope warning

  ) {    
    /* Saving user data in localstorage when 
    logged in and setting up null when logged out */
    this.afAuth.authState.subscribe(user => {
      if (user) {
        this.userData = user;
        localStorage.setItem('user', JSON.stringify(this.userData));
        JSON.parse(localStorage.getItem('user'));
        this.UserID = this.userData.uid;
      } else {
        localStorage.setItem('user', null);
        JSON.parse(localStorage.getItem('user'));
      }
    })
  }

  SignUp(username, email, password) {
    return this.afAuth.auth.createUserWithEmailAndPassword(email, password)
      .then((result) => {
        // set account  doc 
          let created_data = JSON.parse(JSON.stringify(result.user));
          const account = {
          uid: result.user.uid,
          created_time: created_data.createdAt,
          email:  result.user.email,
          display_name: username,
          photoURL: result.user.photoURL,
        }
        this.SetUserData(account);
      }).catch((error) => {
        window.alert(error.message)
      })
  }

  /* Setting up user data when sign in with username/password, 
  sign up with username/password and sign in with social auth  
  provider in Firestore database using AngularFirestore + AngularFirestoreDocument service */
  SetUserData(user) {
    const userRef: AngularFirestoreDocument<User> = this.afs.doc(`users/${user.uid}`);
    const userData: User = {
      bio: null,
      country: {
        country: null,
        country_code:null,
        symbol:null
      },
      gender: "unspecified",
      languages: null,
      profile_pic: user.photoURL,
      username: user.display_name,
    }
    return userRef.set(userData, { 
      merge: true
    })
  }
}

以及我的dashboard.component.ts

export class DashboardComponent implements OnInit {

  isLoggedIn$: Observable<boolean>;
  isLoggedOut$:Observable<boolean>;

  constructor(
    public afAuth: AngularFireAuth,
    public authService: AuthService
    ) { }

  ngOnInit() {
    this.isLoggedIn$ = this.afAuth.authState.pipe(map(user => !!user));
    this.isLoggedOut$ = this.isLoggedIn$.pipe(map(loggedIn => !loggedIn));
  }
}

这样,我只能从 firebase.user 中存储的内容获取详细信息,而不能从我的自定义数据库中获取详细信息。 如何根据经过身份验证的用户的 UID 进入特定文档,以便显示个人简介、性别和语言等信息?

这就是我在 dashboard.html 上解析信息的方式

<!-- Main content -->
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4">
  <div class="inner-adjust">
    <div class="pt-3 pb-2 mb-3 border-bottom">
      <h1 class="h2">User Profile</h1>
    </div>
    <!-- Show user data when logged in -->
    <div class="row" *ngIf="authService.userData as user">
        <div class="col-md-12">
        <div class="media">
          <img class="align-self-start mr-5 img-thumbnail rounded-circle" src="{{(user.photoURL) ? user.photoURL : '/assets/placeholder-user.jpg'}}"
            alt="{{user.displayName}}">
          <div class="media-body">
            <h1>Hello: <strong>{{(user.username)}}</strong></h1>
            <p>Email: <strong>{{user.email}}</strong></p>
            <p>Gender: <strong>{{user.gender}}</strong></p>
            <p>Languages: <strong>{{user.languages}}</strong></p>
          </div>
        </div>
      </div>

      <!-- </div> -->
    </div>

  </div>
</main>

最佳答案

我认为没有必要使用 localStorage,只要应用程序正在运行,Firebase 就会发出 authstate,并且如果用户没有登录,authState 返回null

顺便说一句 - 您还在一个地方使用 JSON.parse(JSON.stringify(...)) ,这没有什么意义;)

无论如何,我有类似的设置,这就是我的做法:

在身份验证服务中:

user$ = this.afAuth.authState.pipe(
  switchMap(user => {
    if (user) {
      return this.afs.doc<any>(`users/${user.uid}`).valueChanges();
    } else {
      return of(null);
    }
  })
);

然后我就订阅我需要的user$。通过手动订阅或使用异步管道来完成此操作。如果您想手动订阅,您需要记住在组件销毁时取消订阅。

这里使用异步管道的示例:

user$ = this.authService.user$;

constructor(private authService: AuthService) { }

模板:

<div *ngIf="(user$ | async) as user">
   <h1>Hello: <strong>{{ user.username }}</strong></h1>
</div>

另外,不要使用任何。请为您的数据创建模型(界面是我的偏好)。毕竟我们正在使用 TypeScript ;)

关于AngularFire根据用户身份验证检索文档ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58060028/

相关文章:

javascript - 为什么我的共享服务未在我的组件之间更新?

Angular 获取路由路径 - 未解析的 url

angular - 如何将 Observable 数组属性加载为 Angular Material Table 数据源?

java - Firebase 自动删除记录

android - Firebase 消息 “E/FirebaseCrash: Failed to initialize crash reporting”

validation - Firebase 规则 : allow push but not allow update

react 原生的 Firebase 电子商务分析

angular - 对源地址 'http://localhost:4200' 处的 XMLHttpRequest 的访问已被 CORS 策略阻止

html - Angular Dom Sanitizer HTML 无法复制文本

android - Firebase 崩溃报告如何初始化