Firebase用户对象和自定义Firestore对象

问题描述 投票:0回答:1

我最近问了这个问题,里面有很多信息,但我不认为我问的问题是对的。Google Firebase Angular Firestore switchMap - Firebase错误DocumentReference.set().

我对AngularFireAuth的理解是,你用它来创建一个带有一堆值的User对象,其中大部分值是不可改变的。如果我想添加一个自定义值,我需要通过Google Firestore来实现。

我已经创建了下面的firestore条目,里面有这些信息。.

我还创建了一个用户模型。

export interface User {
  uid: string;
  email: string;
  displayName?: string;
  role: string;
  thursdayCampaign: Boolean;
  menagerieCoast: Boolean;
}

我的理解是,下面的代码应该进入内置的AngularFireAuth User对象来获取uid,然后我应该使用switchMap重定向到我的firebase商店。我遇到的问题是,当我登录时,this.updateUserData收到了正确的凭证,然后试图用我在那里创建的数据常量更新AngularFireAuth用户对象。这导致函数抛出一个错误,因为userRef.set(data, { merge: true})试图将角色、thursdayCampaign和menagerieCoast合并到AngularFireAuth用户对象中,而这些值在该对象中并不存在。

我的问题是为什么我的引用没有重定向。我是否需要在某个地方调用this.user$?

问题代码如下。我希望我问的方式比我之前的问题更好。

import { Injectable } from "@angular/core";
import { Router } from '@angular/router';

import { auth } from 'firebase/app';
import {
    AngularFirestore,
    AngularFirestoreDocument
} from '@angular/fire/firestore'

import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { User } from './user1.model';

import * as firebase from 'firebase';
import { AngularFireAuth } from '@angular/fire/auth';



@Injectable({
  providedIn: 'root'
})
export class AuthService {

  user$: Observable<User[]>;

  constructor(private afAuth: AngularFireAuth,
              private afs: AngularFirestore,
              private router: Router) {

        //This is how we're getting into the firestoreDB        
        this.user$ = this.afAuth.authState.pipe(
          switchMap(user => {
            if (user){
              return this.afs.doc<User>(`/users/${user.uid}`).valueChanges();
            } else {
                return of(null)
            }
          })
        )
              } //end constructor

  public updateUserData(user){
    //sets user data to firestore on login
    const userRef: AngularFirestoreDocument<User> = this.afs.doc(`users/${user.uid}`)
    console.log("userRef", userRef)
    const data: User = {
      uid: user.uid,
      email: user.email,
      displayName: user.displayName,
      role: user.role,
      thursdayCampaign: user.thursdayCampaign,
      menagerieCoast: user.menagerieCoast
    }
    console.log("data", data)
     userRef.set(data, { merge: true})
  }


  async emailSignin(value){
    //const provider = new auth.EmailAuthProvider();
    const credential = await this.afAuth.signInWithEmailAndPassword(value.email, value.password)
    return this.updateUserData(credential.user), 
    this.router.navigate(['/home'])
  }


  async googleSignin(){
    const provider = new auth.GoogleAuthProvider();
    const credential = await this.afAuth.signInWithPopup(provider);
    return this.updateUserData(credential.user)
  }

当调用emailSignin.User$时出错。

ERROR Error: 未捕获(在承诺中)。FirebaseError: [code=invalid-argument]。函数DocumentReference.set()以无效数据调用。不支持的字段值:未定义(在字段角色中发现)FirebaseError.Function DocumentReference.set()调用无效数据。函数DocumentReference.set()被调用时数据无效。不支持的字段值:未定义(在字段角色中找到)。

angular typescript firebase google-cloud-firestore angularfire
1个回答
1
投票

如果 updateUserData 函数只在实际认证时被调用,你可以简单地删除掉 role, thursdayCampaign, menagerieCoast 的数据有效载荷。

这是因为 { merge: true} 确保只有有效载荷中的数据被改变,而不是整个文档,所以你在文档中的其他已有字段将不会被触动,你也不会再收到这个错误。

updateUserData 方法实际上是新用户登录所需要的,因为它将数据从firebase auth反映到你的firestore数据库中,也就是说,它是在数据库中创建你的唯一uid的地方。如果你需要在你的应用程序执行的稍后阶段更新用户,我建议你为此创建一个单独的方法。

注意:如果你需要更新用户,我建议你创建一个单独的方法。: 其实在你的问题评论上分享的视频教程中就有介绍。这里是社区关于类似问题的参考。联系.

© www.soinside.com 2019 - 2024. All rights reserved.