1
votes

I'm following this tutorial to create users with Email and password in Firebase: https://angularfirebase.com/lessons/google-user-auth-with-firestore-custom-data/ with createUserWithEmailAndPassword.

Is it possible to add a field so that the user can enter their name and then store it in Firestore?

So far I have this and it works correctly:

component.html

<form [formGroup]="forma" (ngSubmit)="emailSignUp()" novalidate>
  <!-- <div class="form-group">
    <input type="text" class="form-control" placeholder="Nombre" formControlName="displayName">
  </div> -->
  <div class="form-group">
    <input type="email" class="form-control" placeholder="Email" formControlName="email">
  </div>
  <div class="form-group">
    <input type="password" class="form-control" placeholder="ContraseƱa" formControlName="password">
  </div>
  <div class="my-2">
    <button class="btn btn-primary btn-block" type="submit" >Crear cuenta</button>
  </div>
</form>

components.ts

this.forma = fb.group ({
  //displayName: ['', Validators.required],
  email: [ '', [Validators.required, Validators.email] ],
  password: [ '', Validators.required ],
})

emailSignUp() {
  this.auth.emailSignUp(this.forma.value.email, this.forma.value.password)
}

service.ts

interface User {
  uid: string;
  email: string;
  photoURL?: string;
  displayName?: string;
  favoriteColor?: string;
  fechaRegistro?: string;
}

constructor( private afAuth: AngularFireAuth, private afs: AngularFirestore) { 
  this.user = this.afAuth.authState.pipe(
    switchMap(user => {
      if (user) {
        return this.afs.doc<User>(`users/${user.uid}`).valueChanges()
      } else {
        return of(null)
      }
    })
  )
}

emailSignUp(email: string, password: string) {
return this.afAuth.auth
  .createUserWithEmailAndPassword(email, password)
  .then(credential => {
    this.pushUserData(credential.user);
    console.log('Usuario creado')
    this.router.navigate(['/login'])
  })
  .catch(error => {
    this.handleError(error)
  });
}

private pushUserData( user: User ) {
const userRef: AngularFirestoreDocument<User> = this.afs.doc(`users/${user.uid}`);
const data: User = {
  uid: user.uid,
  email: user.email,
};
userRef.set(data, {merge: true});
}
4

4 Answers

3
votes

use the updateProfile method

register(email:string, password: string, fullname:string){
  return new Promise((resolve, reject) => {
    this.afAuth.auth.createUserWithEmailAndPassword(email, password)
    .then(userData => {
      userData.user.updateProfile({
        displayName: fullname,
        photoURL: ''
      }).then(() => {
        this.updateUserData(userData.user);
        resolve(userData);
      }); 
    },
    err => reject(err))
  });
}
0
votes

just add new input and pass it to the emailSignUp method, save it in temporery property of the service and save it to firestore in the pushUserData method

component.html

<div class="form-group">
    <input type="email" class="form-control" placeholder="Email" formControlName="email">
  </div>

components.ts

this.forma = fb.group ({
  //displayName: ['', Validators.required],
  email: [ '', [Validators.required, Validators.email] ],
  password: [ '', Validators.required ],
  displayName: [ '', Validators.required ],
})

emailSignUp() {
  this.auth.emailSignUp(this.forma.value.email, this.forma.value.password, this.forma.value.displayName)
}

service.ts

emailSignUp(email: string, password: string, displayName: string) {
this._displayName = displayName ;
return this.afAuth.auth
  .createUserWithEmailAndPassword(email, password)
  .then(credential => {
    this.pushUserData(credential.user);
    console.log('Usuario creado')
    this.router.navigate(['/login'])
  })
  .catch(error => {
    this.handleError(error)
  });
}

private pushUserData( user: User ) {
const userRef: AngularFirestoreDocument<User> = this.afs.doc(`users/${user.uid}`);
const data: User = {
  uid: user.uid,
  email: user.email,
  displayName:this._displayName
};
userRef.set(data, {merge: true});
}
0
votes

If you want to add an User doc to firestore just add the data "name, photo, address..." to pushUserData() method.

private pushUserData( user: User ) {
const userRef: AngularFirestoreDocument<User> = this.afs.doc(`users/${user.uid}`);
const data: User = {
  uid: user.uid,
  email: user.email,
  displayName: "exampleName",    <-------
  photoUrl: 'https://photo....'  <-------
};
userRef.set(data, {merge: true});
}

Now, if you want to set the displayName field of firebase auth data, just update de firebase user profile before the push method. Like this...

emailSignUp(email: string, password: string) {
return this.afAuth.auth
  .createUserWithEmailAndPassword(email, password)
  .then(credential => {

    // ------------- update profile ------------- //
    credential.user.updateProfile({
       displayName: "exampleName",
       photoUrl: "https://photo..."
    })
    // ------------------------------------------ //

    this.pushUserData(credential.user);
    console.log('Usuario creado')
    this.router.navigate(['/login'])
  })
  .catch(error => {
    this.handleError(error)
  });
}

If you do not want to add an User doc to Firestore and just use the Firestore Auth data, you don`t need the pushUserData() method.
-1
votes

You need to add private displayName: string; in your service.ts