Firebase 用户对象和自定义 Firestore 对象
Firebase User Object and Custom Firestore Object
我最近问了这个问题,里面有很多信息,但我认为我问的问题不对。 Google Firebase Angular Firestore switchMap - Firebase Error 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 store。我遇到的问题是,当我登录时,this.updateUserData 收到正确的凭据,然后尝试使用我在那里创建的数据常量更新 AngularFireAuth 用户对象。这导致函数抛出错误,因为 userRef.set(data, { merge: true}) 试图将角色、thursdayCampaign 和 menagerieCoast 合并到 AngularFireAuth User 对象中,而这些值在该对象上不存在.
我的问题是为什么我的引用没有重定向。我需要在什么地方打电话给 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 时出错:
ERROR Error: Uncaught (in promise): FirebaseError: [code=invalid-argument]: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field role)
FirebaseError: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field role)
如果 updateUserData
函数仅在实际身份验证时被调用,您可以简单地从数据负载中删除 role
、thursdayCampaign
、menagerieCoast
。
这是因为 { merge: true}
确保只有有效载荷中存在的数据被更改,而不是整个文档,因此文档中其他预先存在的字段将保持不变,您不会不再出现该错误。
新用户登录实际上需要 updateUserData
方法,因为它将来自 firebase auth 的数据反映到您的 firestore 数据库中,也就是说,它是在数据库上创建您的唯一 uid 的地方。如果您需要在稍后执行应用程序时更新用户,我建议您为此创建一个单独的方法。
注意:这实际上在您在问题评论中分享的视频教程中有所描述。 link.
供社区参考类似问题
我最近问了这个问题,里面有很多信息,但我认为我问的问题不对。 Google Firebase Angular Firestore switchMap - Firebase Error 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 store。我遇到的问题是,当我登录时,this.updateUserData 收到正确的凭据,然后尝试使用我在那里创建的数据常量更新 AngularFireAuth 用户对象。这导致函数抛出错误,因为 userRef.set(data, { merge: true}) 试图将角色、thursdayCampaign 和 menagerieCoast 合并到 AngularFireAuth User 对象中,而这些值在该对象上不存在.
我的问题是为什么我的引用没有重定向。我需要在什么地方打电话给 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 时出错:
ERROR Error: Uncaught (in promise): FirebaseError: [code=invalid-argument]: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field role) FirebaseError: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field role)
如果 updateUserData
函数仅在实际身份验证时被调用,您可以简单地从数据负载中删除 role
、thursdayCampaign
、menagerieCoast
。
这是因为 { merge: true}
确保只有有效载荷中存在的数据被更改,而不是整个文档,因此文档中其他预先存在的字段将保持不变,您不会不再出现该错误。
新用户登录实际上需要 updateUserData
方法,因为它将来自 firebase auth 的数据反映到您的 firestore 数据库中,也就是说,它是在数据库上创建您的唯一 uid 的地方。如果您需要在稍后执行应用程序时更新用户,我建议您为此创建一个单独的方法。
注意:这实际上在您在问题评论中分享的视频教程中有所描述。 link.
供社区参考类似问题