Ваши пользовательские свойства не существуют для типа firebase.UserCredential, который возвращается из createUserWithEmailAndPassword или встроенных методов входа в систему. Вам нужно будет передать свои пользовательские данные в методы авторизации и / или входа в систему, сохранить их, а затем передать их в метод SetUserData.
Вот что должно работать:
auth.service.ts:
import { Injectable, NgZone } from '@angular/core';
import { User } from "../services/user";
import { auth } from 'firebase/app';
import { AngularFireAuth } from "@angular/fire/auth";
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { Router } from "@angular/router";
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
@Injectable({
providedIn:'root'
})
export class AuthService {
userData: any; // Save logged in user data
user: Observable<User>;
constructor(
private afs: AngularFirestore, // Inject Firestore service
private afAuth: AngularFireAuth, // Inject Firebase auth service
private router: Router,
private ngZone: NgZone // NgZone service to remove outside scope warning
) {
this.user = this.afAuth.authState.pipe(switchMap(user => {
if(user){
this.userData = user;
localStorage.setItem('user', JSON.stringify(this.userData));
JSON.parse(localStorage.getItem('user'));
return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
}
else {
localStorage.setItem('user', null);
JSON.parse(localStorage.getItem('user'));
return of(null);
}
}))
}
// Sign in with email/password
SignIn(email, password){
return this.afAuth.auth.signInWithEmailAndPassword(email, password)
.then(() => {
this.user.subscribe(user => {
await this.SetUserData(user);
this.ngZone.run(() => {
this.router.navigate(['dashboard']);
});
});
}).catch((error) => {
window.alert(error.message)
});
}
// Sign up with email/password
SignUp(userData: User) {
return this.afAuth.auth.createUserWithEmailAndPassword(userData.email, userData.password)
.then(() => {
/* Call the SendVerificaitonMail() function when new user sign
up and returns promise */
this.SendVerificationMail();
this.SetUserData(userData);
}).catch((error) => {
window.alert(error.message)
})
}
// Send email verfificaiton when new user sign up
SendVerificationMail(){
return this.afAuth.auth.currentUser.sendEmailVerification()
.then(() => {
this.router.navigate(['verify-email-address']);
})
}
// Reset Forgot password
ForgotPassword(passwordResetEmail){
window.alert('forgot password');
return this.afAuth.auth.sendPasswordResetEmail(passwordResetEmail)
.then(() => {
window.alert('Password reset email sent, check your inbox.');
}).catch((error) => {
window.alert(error);
})
}
// Returns true when user is logged in and email is verified
get isLoggedIn(): boolean {
const user = JSON.parse(localStorage.getItem('user'));
return (user !== null && user.emailVerified !== false) ?true : false;
}
// Sign in with Google
GoogleAuth(userData){
return this.AuthLogin(new auth.GoogleAuthProvider(), userData);
}
// Auth logic to run auth providers
AuthLogin(provider, userData){
return this.afAuth.auth.signInWithPopup(provider)
.then(() => {
this.SetUserData(userData);
this.ngZone.run(() => {
this.router.navigate(['dashboard']);
})
}).catch((error) => {
window.alert(error)
})
}
/* 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<any> = this.afs.doc(`user/${user.uid}`);
const userData: User = {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL,
emailVerified: user.emailVerified,
firstName: user.firstName,
lastName: user.lastName,
birthday: user.birthday,
addressOne: user.addressOne,
addressTwo: user.addressTwo,
zipCode: user.zipCode,
city: user.city,
phoneOne: user.phoneOne,
phoneTwo: user.phoneTwo,
profilType: user.profilType,
profilPicture: user.profilPicture,
admin: user.admin,
moderator: user.admin
}
return userRef.set(userData, {
merge: true
})
}
// Sign Out
SignOut(){
return this.afAuth.auth.signOut().then(() => {
localStorage.removeItem('user');
this.router.navigate(['home']);
})
}
}
Я хотел бы рассмотреть возможность использования построителя форм в вашем компоненте регистрации, например:
signup.component.ts:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AuthService } from 'src/app/core/auth.service'; // Or the path to your Auth Service
@Component({
selector: 'signup', // Or your signup component selector
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.scss']
})
export class SignupComponent implements OnInit {
signUpForm: FormGroup = this.fb.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required]],
displayName: ['', [Validators.required]],
firstName: ['', [Validators.required]],
lastName: ['', [Validators.required]],
addressOne: ['', [Validators.required]],
addressTwo: [''],
zipCode: ['', [Validators.required]],
city: ['', [Validators.required]],
phoneOne: ['', [Validators.required]],
phoneTwo: [''],
profilType: ['', [Validators.required]]
});
constructor(
private fb: FormBuilder,
private auth: AuthService,
) {}
ngOnInit() {}
signUpViaEmail() {
this.auth.SignUp(this.signUpForm.value);
}
googleLogin() {
this.auth.GoogleAuth(this.signUpForm.value);
}
}
signup.component.html:
<div class="page-heading clearfix asset-bg alt-one">
<div class="container">
<div class="heading-text">
<h1 class="entry-title">Register</h1>
</div>
</div>
</div>
<div id="page-wrap">
<div class="inner-page-wrap has-no-sidebar no-bottom-spacing no-top-spacing clearfix">
<div class="page-content clearfix">
<section class="container">
<div class="row">
<div class="blank_spacer col-md-12"></div>
</div>
</section>
<section class="container">
<div class="row">
<div class="col-md-12 register-wrap">
<div class="authBlock">
<h2 class="spb-heading spb-text-heading"><span>Register</span></h2>
<form [formGroup]="signUpForm" class="form-group">
<input type="text" class="form-control" placeholder="First Name" #userFirstName formControlName="firstName" required>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Last Name" #userLastName formControlName="lastName" required>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Desired Display Name" #displayName formControlName="displayName" required>
</div>
<div class="form-group">
<input type="email" class="form-control" placeholder="Email Address" #userEmail formControlName="email" required>
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="Password" #userPwd formControlName="password" required>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Address" #userAddressOne formControlName="addressOne" required>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Address" #userAddressTwo formControlName="addressTwo">
</div>
<div class="form-group">
<input type="number" class="form-control" placeholder="Zip code" #userZipCode formControlName="zipCode" required>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="City" #userCity formControlName="city" required>
</div>
<div class="form-group">
<input type="tel" class="form-control" placeholder="Phone One" #userPhoneOne formControlName="phoneOne" required>
</div>
<div class="form-group">
<input type="tel" class="form-control" placeholder="Phone Two" #userPhoneTwo formControlName="phoneTwo">
</div>
<div class="form-group">
<select name="" #userProfil formControlName="profilType" required>
<option value="">Select your profil type</option>
<option value="personnal">Particulier</option>
<option value="office">Société</option>
</select>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary" (click)="signUpViaEmail()">Sign Up</button>
</div>
<div class="form-group">
<span class="or"><span class="orInner">Or</span></span>
</div>
<!-- Continue with Google -->
<div class="form-group">
<button type="submit" class="btn googleBtn" (click)="googleLogin()">
<i class="fa fa-google-plus"></i>
Continue with Google
</button>
</div>
<!-- Continue with Facebook -->
<div class="form-group">
<button type="button" class="btn facebookBtn" (click)="authService.FacebookAuth()">
<i class="fa fa-facebook"></i>
Continue with Facebook
</button>
</div>
</form>
<div class="redirectToLogin">
<span>Already have an account? <span class="redirect" routerLink="/sign-in">Log In</span></span>
</div>
</div>
</div>
</section>
</div>
</div>
</div>