使用 FirebaseAuthentication 创建用户后,Firebase 不会将用户数据保存到 Firestore - Angular 9
Firebase does not save userdata to Firestore after creating user with FirebaseAuthentication - Angular 9
我有一个 Angular 9 网络应用程序,到目前为止,我已经让它与 Firestore 配合得很好。我有一个用于添加用户的表单,该表单将用户正确保存到 Firestore,但没有将它们添加到 Authenticated users,添加功能将在我删除时删除解决以下问题。
users.component.ts:
this.userService.addUser(user);
在 userService 中我调用:
async addUser(user: User) {
await this.firestore.collection('users').doc(user.email).set(user);
}
问题是当我想用FirebaseAuthentication注册新用户时,用户数据没有保存在用户collection。当用户在 register.component.ts 中点击 Register 我调用:
register() {
this.authenticationService
.register(this.form.controls['email'].value, this.form.controls['password'].value)
.then(() => {
this.userService.addUser({
nickname: this.form.controls['nickname'].value,
email: this.form.controls['email'].value,
role: 'Customer',
});
})
.catch((error) => {
console.log(error);
});
}
authenticationService.ts中的注册方法:
register(email: string, password: string) {
return this.angularFireAuth.auth.createUserWithEmailAndPassword(email, password);
}
我尝试了不同的方法,使用 Promises、async / await、直接从 authenticationService.ts 中的注册方法调用、使用 collection('users').add 而不是设置,使用 uid 作为文档 uid 而不是电子邮件的响应。
我倾向于认为有某种回滚机制,因为我订阅了数据$:
this.firestore
.collection<User>(this.path)
.snapshotChanges()
.pipe(
takeUntil(this.destroy$),
map((items) => {
return items.map((item) => {
const data = item.payload.doc.data() as User;
return {
...data,
};
});
})
)
.subscribe((data) => {
this.users$.next(data);
});
在register.component.ts ngOnInit:
this.userService.users$.subscribe((data) => {
console.log(data);
});
这给了我一些见解:
对象瞬间触发两次,先是4个元素,然后是3个
users.component.ts
constructor(private userService: UserService, public dialog: MatDialog) {}
register.component.ts
constructor(
private userService: UserService,
private formBuilder: FormBuilder,
private authenticationService: AuthenticationService
) {}
这两个组件都是同一个模块的一部分,但出于某种原因,如果我导航到 users.component.ts,然后导航到 register.component.ts 保存用户 有效 !它被添加到 Authenticated users 和 Firestore 用户 collection.
我在任何时候都没有收到任何错误。
所以我真的不知道是什么导致它的行为不同,但我需要它从 register.component.ts 开始工作,而不是先导航到 users.component.ts.
编辑:
我的规则:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// This rule allows anyone on the internet to view, edit, and delete
// all data in your Firestore database. It is useful for getting
// started, but it is configured to expire after 30 days because it
// leaves your app open to attackers. At that time, all client
// requests to your Firestore database will be denied.
//
// Make sure to write security rules for your app before that time, or else
// your app will lose access to your Firestore database
match /{document=**} {
allow read, write: if request.time < timestamp.date(2020, 8, 6);
}
}
}
如果您看到这样的回滚,这通常意味着服务器根据您为数据库指定的安全规则拒绝了写入操作。所以看起来用户没有写入权限。
您必须修改 security rules of the database to allow the user to write their profile data。
您必须手动将创建的用户添加到您的 collection。
createUserWithEmailAndPassword() 成功执行后,您应该调用一个自定义函数来获取用户 Object 并将其保存到 Firestore。
示例:
register(email: string, password: string) {
let rs = this.angularFireAuth.auth.createUserWithEmailAndPassword(email, password);
return this.saveUser(rs.user)
}
saveUser(user){
const userRef: AngularFirestoreDocument<User> = this.angularFistore.doc(`users/${user.email}`);
userRef.get().subscribe(snapDoc =>{
if(!snapDoc.exists){
const data; //Initialize
//do anything else
return userRef.set(data, { merge: true })
})
}
我有一个 Angular 9 网络应用程序,到目前为止,我已经让它与 Firestore 配合得很好。我有一个用于添加用户的表单,该表单将用户正确保存到 Firestore,但没有将它们添加到 Authenticated users,添加功能将在我删除时删除解决以下问题。
users.component.ts:
this.userService.addUser(user);
在 userService 中我调用:
async addUser(user: User) {
await this.firestore.collection('users').doc(user.email).set(user);
}
问题是当我想用FirebaseAuthentication注册新用户时,用户数据没有保存在用户collection。当用户在 register.component.ts 中点击 Register 我调用:
register() {
this.authenticationService
.register(this.form.controls['email'].value, this.form.controls['password'].value)
.then(() => {
this.userService.addUser({
nickname: this.form.controls['nickname'].value,
email: this.form.controls['email'].value,
role: 'Customer',
});
})
.catch((error) => {
console.log(error);
});
}
authenticationService.ts中的注册方法:
register(email: string, password: string) {
return this.angularFireAuth.auth.createUserWithEmailAndPassword(email, password);
}
我尝试了不同的方法,使用 Promises、async / await、直接从 authenticationService.ts 中的注册方法调用、使用 collection('users').add 而不是设置,使用 uid 作为文档 uid 而不是电子邮件的响应。
我倾向于认为有某种回滚机制,因为我订阅了数据$:
this.firestore
.collection<User>(this.path)
.snapshotChanges()
.pipe(
takeUntil(this.destroy$),
map((items) => {
return items.map((item) => {
const data = item.payload.doc.data() as User;
return {
...data,
};
});
})
)
.subscribe((data) => {
this.users$.next(data);
});
在register.component.ts ngOnInit:
this.userService.users$.subscribe((data) => {
console.log(data);
});
这给了我一些见解:
对象瞬间触发两次,先是4个元素,然后是3个
users.component.ts
constructor(private userService: UserService, public dialog: MatDialog) {}
register.component.ts
constructor(
private userService: UserService,
private formBuilder: FormBuilder,
private authenticationService: AuthenticationService
) {}
这两个组件都是同一个模块的一部分,但出于某种原因,如果我导航到 users.component.ts,然后导航到 register.component.ts 保存用户 有效 !它被添加到 Authenticated users 和 Firestore 用户 collection.
我在任何时候都没有收到任何错误。
所以我真的不知道是什么导致它的行为不同,但我需要它从 register.component.ts 开始工作,而不是先导航到 users.component.ts.
编辑:
我的规则:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// This rule allows anyone on the internet to view, edit, and delete
// all data in your Firestore database. It is useful for getting
// started, but it is configured to expire after 30 days because it
// leaves your app open to attackers. At that time, all client
// requests to your Firestore database will be denied.
//
// Make sure to write security rules for your app before that time, or else
// your app will lose access to your Firestore database
match /{document=**} {
allow read, write: if request.time < timestamp.date(2020, 8, 6);
}
}
}
如果您看到这样的回滚,这通常意味着服务器根据您为数据库指定的安全规则拒绝了写入操作。所以看起来用户没有写入权限。
您必须修改 security rules of the database to allow the user to write their profile data。
您必须手动将创建的用户添加到您的 collection。 createUserWithEmailAndPassword() 成功执行后,您应该调用一个自定义函数来获取用户 Object 并将其保存到 Firestore。 示例:
register(email: string, password: string) {
let rs = this.angularFireAuth.auth.createUserWithEmailAndPassword(email, password);
return this.saveUser(rs.user)
}
saveUser(user){
const userRef: AngularFirestoreDocument<User> = this.angularFistore.doc(`users/${user.email}`);
userRef.get().subscribe(snapDoc =>{
if(!snapDoc.exists){
const data; //Initialize
//do anything else
return userRef.set(data, { merge: true })
})
}