如何在我的角度Firebase数据库的注册表单中添加角度自定义盾牌?

时间:2019-04-16 16:51:46

标签: angular firebase firebase-realtime-database firebase-authentication

因此,我遵循一个教程来使用Firebase Auth创建我的角度应用程序。

此刻,一切正常。

但是

我第一次搜索使用自定义字段创建一个真正的注册表单,并将其添加到我的firebase auth注册方法中

我已经编辑了现有的注册表单,并在他上添加了自定义字段 并尝试添加我的个人“用户”界面。

我在我的Firebase项目中使用angular 7

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";
@Injectable({
providedIn:'root'
})
export class AuthService {
    userData: any; // Save logged in user data
    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.afAuth.authState.subscribe(user => {
            if(user){
                this.userData = user;
                localStorage.setItem('user', JSON.stringify(this.userData));
                JSON.parse(localStorage.getItem('user'));
            }
            else {
                localStorage.setItem('user', null);
                JSON.parse(localStorage.getItem('user'));
            } 
        })
    }
    // Sign in with email/password
    SignIn(email, password){
        return this.afAuth.auth.signInWithEmailAndPassword(email, password)
        .then((result) => {
            this.ngZone.run(() => {
                this.router.navigate(['dashboard']);
            });
            this.SetUserData(result.user);
        }).catch((error) =>{
            window.alert(error.message)
        })
    }
    // Sign up with email/password
    SignUp(email, password) {
        return this.afAuth.auth.createUserWithEmailAndPassword(email, password)
        .then((result) => {
            /* Call the SendVerificaitonMail() function when new user sign 
            up and returns promise */
            this.SendVerificationMail();
            this.SetUserData(result.user);
        }).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 Forggot 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 looged 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(){
        return this.AuthLogin(new auth.GoogleAuthProvider());
    }
    // Auth logic to run auth providers
    AuthLogin(provider){
        return this.afAuth.auth.signInWithPopup(provider)
        .then((result) => {
            this.ngZone.run(() => {
                this.router.navigate(['dashboard']);
            })
            this.SetUserData(result.user);
        }).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']);
        })
    }
}

我的自定义注册表格

<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>
              <div class="form-group">
                <input type="text" class="form-control" placeholder="First Name" #userFirstName required>
              </div>
              <div class="form-group">
                <input type="text" class="form-control" placeholder="Last Name" #userLastName required>
              </div>              
              <div class="form-group">
                <input type="email" class="form-control" placeholder="Email Address" #userEmail required>
              </div>
              <div class="form-group">
                <input type="password" class="form-control" placeholder="Password" #userPwd required>
              </div>
              <div class="form-group">
                <input type="text" class="form-control" placeholder="Address" #userAddressOne required>
              </div>
              <div class="form-group">
                <input type="text" class="form-control" placeholder="Address" #userAddressTwo>
              </div>              
              <div class="form-group">
                <input type="number" class="form-control" placeholder="Zip code" #userZipCode required>
              </div>
              <div class="form-group">
                <input type="text" class="form-control" placeholder="City" #userCity required>
              </div>
              <div class="form-group">
                <input type="tel" class="form-control" placeholder="Phone One" #userPhoneOne required>
              </div>
              <div class="form-group">
                <input type="tel" class="form-control" placeholder="Phone Two" #userPhoneTwo>
              </div>
              <div class="form-group">
                <select name="" #userProfil 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">
                <input type="button" class="btn btn-primary" value="Sign Up" (click)="authService.SignUp(userEmail.value, userPwd.value)">
              </div>
              <div class="form-group">
                <span class="or"><span class="orInner">Or</span></span>
              </div>
            <!-- Continue with Google -->
              <div class="form-group">
                <button type="button" class="btn googleBtn" (click)="authService.GoogleAuth()">
                  <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>
            </div>
            <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>

我的user.ts界面

export interface User {
    uid: string;
    email: string;
    displayName: string;
    photoURL: string;
    emailVerified: boolean;
    // firstName: string;
    // lastName: string;
    // birthday: Date;
    // addressOne: string;
    // addressTwo: string;
    // zipCode: string;
    // city: string;
    // phoneOne: string;
    // phoneTwo: string;
    // profilType: string;
    // profilPicture: string;
    // admin: boolean;
    // moderator: boolean;
 }

当我尝试在自定义字段中注册时,控制台面板出现错误

此错误:“ src / app / shared / services / auth.service.ts(112,13)中的错误:错误TS2322:键入'{uid:任意;电子邮件:任意; displayName:任意; photoURL:任意; emailVerified:任何; firstName:任何; lastName:任何;生日:任何; addressOne:任何; addressTwo:任何;邮编:任何;城市:任何; phoneOne:任何; phoneTwo:任何; profilType:任何; profilPicture:任何; admin:任何;主持人:任何;}}均不可分配给“用户”类型。   对象文字只能指定已知的属性,类型'User'中不存在'profilType'。”

所以我努力了解如何将这个自定义字段实现为注册方法

1 个答案:

答案 0 :(得分:1)

您的自定义属性在firebase.UserCredential类型上不存在,该类型从createUserWithEmailAndPassword或内置的signIn方法返回。您需要将自定义数据传递到auth signUp和/或登录方法,保留它,然后将其传递到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>