我按照this tutorial构建了一个注册表单,允许将附加数据添加到用户对象。
我改变了一些东西,因为我需要一步注册表。我没有理由只为添加用户名做一个辅助步骤。
这是我的模特:
export class UserModel implements UserInterface.Root {
uid: string;
email: string;
displayName: string;
firstName?: string;
lastName?: string;
photoURL?: string;
constructor(user) {
this.uid = user.uid;
this.email = user.email;
this.displayName = user.displayName;
this.firstName = user.firstName || 'No first name';
this.lastName = user.lastName || 'No last name';
this.photoURL = user.photoURL;
}
}
这是我的auth.service:
@Injectable()
export class AuthService {
user: Observable<UserModel>;
constructor(private afAuth: AngularFireAuth,
private afs: AngularFirestore,
private router: Router,
private notify: NotifyService) {
this.user = this.afAuth.authState
.switchMap(user => {
if (user) {
return this.afs.doc<UserModel>(`users/${user.uid}`).valueChanges();
} else {
return Observable.of(null);
}
});
}
//// Email/Password Auth ////
emailSignUp(email: string, password: string) {
return this.afAuth.auth.createUserWithEmailAndPassword(email, password)
.then(user => {
return this.setUserDoc(user); // create initial user document
})
.catch(error => this.handleError(error));
}
// Update properties on the user document
updateUser(user: UserModel, data: any) {
return this.afs.doc(`users/${user.uid}`).update(data);
}
// Sets user data to firestore after succesful login
private setUserDoc(user) {
const userRef: AngularFirestoreDocument<UserModel> = this.afs.doc(`users/${user.uid}`);
const data: UserModel = {
uid: user.uid,
email: user.email || null,
photoURL: user.photoURL || 'url to default image',
displayName: user.displayName,
firstName: user.firstName || 'No first name',
lastName: user.lastName || 'No last name'
};
return userRef.set(data);
}
}
这里的register.componentts带有触发错误的signUp函数:
export class SiteAuthRegisterComponent implements OnInit {
signUpForm: FormGroup;
userState;
constructor(public auth: AuthService, private fb: FormBuilder) {
}
ngOnInit() {
this.userState = this.auth.user.map(user => {
if (user) {
return user.displayName ? 'complete' : 'incomplete';
}
});
this.signUpForm = this.fb.group({
'email': ['', [
Validators.required,
Validators.email
]],
'displayName': ['', [
Validators.required
]],
'password': ['', [
Validators.pattern('^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$'),
Validators.minLength(6),
Validators.maxLength(25)
]]
});
}
// Using getters will make your code look pretty
get email() {
return this.signUpForm.get('email');
}
get password() {
return this.signUpForm.get('password');
}
get displayName() {
return this.signUpForm.get('displayName');
}
signUp() {
return this.auth.emailSignUp(this.email.value, this.password.value).then((user) => {
console.log(user);
return this.auth.updateUser(new UserModel(user), {
displayName: this.displayName.value
});
}
);
}
}
register.component.html
<section class="site-register dark-theme">
<div class="site-register-inner">
<mat-card class="auth-wrapper">
<div class="auth-brand">
<div class="auth-brand-inner">
<img src="/assets/animesector-logo.svg" alt="Logo">
</div>
</div>
<div class="auth-form" *ngIf="(auth.user | async) || {} as user">
<h1>Create Account</h1>
<form [formGroup]="signUpForm" *ngIf="!user.uid" (ngSubmit)="signUp()">
<mat-form-field>
<input matInput type="text" placeholder="E-Mail" formControlName="email" autocomplete="off">
<mat-error *ngIf="!signUpForm.controls['email'].valid && signUpForm.controls['email'].touched">
No Idea... This Shit is complicated
</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput type="text" placeholder="Benutzername" formControlName="displayName">
<mat-error *ngIf="!signUpForm.controls['displayName'].valid && signUpForm.controls['displayName'].touched">
Please enter a valid displayName
</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput type="password" placeholder="Password" formControlName="password">
<mat-error *ngIf="!signUpForm.controls['password'].valid && signUpForm.controls['password'].touched">
Please enter a valid email Password
</mat-error>
</mat-form-field>
<button mat-raised-button color="primary" [disabled]="!signUpForm.valid">Sign Up</button>
</form>
<!--
<form [formGroup]="detailForm" *ngIf="user.uid && !user.displayName" (ngSubmit)="setDisplayName(user)">
<mat-form-field>
<input matInput type="text" placeholder="displayName" formControlName="displayName">
<mat-error *ngIf="!detailForm.controls['displayName'].valid && detailForm.controls['displayName'].touched">
Please enter a valid displayName
</mat-error>
</mat-form-field>
<button mat-raised-button color="primary" [disabled]="!detailForm.valid">Sign Up</button>
</form>
<div class="registration-success" *ngIf="user.displayName">
Your have completed the registration!
</div> -->
<footer>
<p>Mit deiner Registrierung akzeptierst du die <a href="/#">AGB</a> und <a href="/#">Datenschutzerklärung</a> von animesector</p>
<div class="divider"></div>
<p>Hast du bereits einen Account? <a [routerLink]="'/login'">Einloggen</a></p>
</footer>
</div>
</mat-card>
</div>
</section>
signUp函数内部是console.log(用户);返回一个未定义的。但我不明白为什么。 emailSignUp是否会回复承诺?
最后我收到此控制台错误:
ERROR TypeError: Cannot read property 'uid' of undefined
at new UserModel (user.model.ts:10)
at eval (site-auth-register.component.ts:65)
at e.g (auth.js:23)
at Yb (auth.js:26)
at Ub (auth.js:26)
at z.h.Qb (auth.js:25)
at Cb (auth.js:19)
at ZoneDelegate.invoke (zone.js:388)
at Object.onInvoke (core.js:4760)
at ZoneDelegate.invoke (zone.js:387)