typescript - Angular6 Firebase autentifikácia s e-mailom a heslom
Prosím, pomôžte mi, som nový v Angular6 a Firebase programovaní. Mám dobre fungujúci systém autentifikácie Firebase s e-mailom a heslom. Ale pri registrácii môžem pri ukladaní používateľa do databázy získať len UID a e-mail. Čítal som o updateProfile, ale neviem, ako to implementovať vo svojom kóde. Používam "@angular/fire": "^5.0.0", "firebase": "^5.5.1", takže sa pýtam, či je táto verzia dobrá alebo ju musím zmeniť. Späť k otázke: Služba:
import { Injectable } from "@angular/core";
import { AngularFireAuth } from "@angular/fire/auth";
import {
AngularFirestore,
AngularFirestoreCollection,
AngularFirestoreDocument
} from "@angular/fire/firestore";
import { Observable } from "rxjs";
import "rxjs/add/operator/map";
@Injectable()
export class AuthService {
constructor(private afAuth: AngularFireAuth, private db: AngularFirestore) {
// this.afAuth.authState.subscribe(auth => console.log(auth));
}
login(email: string, password: string) {
return new Promise((resolove, reject) => {
this.afAuth.auth
.signInWithEmailAndPassword(email, password)
.then(userData => resolove(userData), err => reject(err));
});
}
getAuth() {
return this.afAuth.authState.map(auth => auth);
}
logout() {
this.afAuth.auth.signOut();
}
register(email: string, password: string) {
return new Promise((resolove, reject) => {
this.afAuth.auth
.createUserWithEmailAndPassword(email, password)
.then(userData => resolove(userData), err => reject(err));
});
}
}
Komponent
import { Component, OnInit } from "@angular/core";
import { AuthService } from "../../service/auth.service";
import { Router } from "@angular/router";
@Component({
selector: "app-register",
templateUrl: "./register.component.html",
styleUrls: ["./register.component.css"]
})
export class RegisterComponent implements OnInit {
email: string;
password: string;
constructor(private authService: AuthService, private router: Router) {}
ngOnInit() {}
onSubmit() {
this.authService
.register(this.email, this.password)
.then(res => {
this.router.navigate(["/"]);
})
.catch(err => console.log(err.message));
}
}
Môj cieľ je mať displayName a skill ako vlastnosť používateľa v databáze. Po registrácii s mojím kódom je displayName null. Takže moja otázka je, ako uložiť displayName do databázy? Ďakujem, Viktor.
Odpoveď č. 1
Vitajte na StackOverflow.
Dôvod, prečo je displayName null, je ten, že je predvolený null (pokiaľ sa neprihlasujete cez sociálnu sieť, ako je Facebook alebo Google). Čo by ste mali zvážiť, je:
- Pri každej registrácii vytvorte nový dokument v zbierke
users(pomenujte ho, ako chcete). - Pri každom prihlásení aktualizujte existujúci dokument používateľa (nemusíte, ale niekedy je to užitočné).
- Získajte používateľský dokument podľa aktuálne overeného používateľa.
Začnime registráciou:
Máte niekoľko spôsobov prihlásenia, ale vysvetlím vám, ako sa to robí cez Email/Heslo.
Takže najprv potrebujeme vytvoriť metódu register, ktorá prijíma parametre email a heslo. Vidím, že ste už metódu vytvorili, ale mali by ste vedieť, že nemusíte obalovať createUserWithEmailAndPassword do promise, pretože už sama o sebe je promise. Po registrácii používateľa pridáme jeho údaje do našej kolekcie:
register(email: string, password: string) {
this.afAuth.auth.createUserWithEmailAndPassword(email, password)
.then(userCredential => this.upsertUserData(userCredential))
.catch(error => this.handleAuthError(error);
}
private upsertUserData(userCredential: firebase.auth.UserCredential) {
// Upsert = Update/Insert.
return this.afs.doc(`users/${userCredential.uid}`).update({
email: userCredential.email
});
}
private handleAuthError(error) {
console.error(error)
}
Ako vidíte, vytvoril som ďalšie dve metódy, aby bola metóda register čistejšia a čitateľnejšia.
Teraz, keď máme registráciu hotovú, vytvorme metódu prihlásenia, ktorá je takmer rovnaká:
login(email: string, password: string) {
this.afAuth.signInWithEmailAndPassword(email, password)
.then(userCredential => this.upsertUserData(userCredential))
.catch(error = > this.handleAuthError(error));
}
Po tom, čo sme sa zaregistrovali a prihlásili do aplikácie, chceme získať údaje používateľa, aby sme to mohli urobiť takto:
export class AuthService {
...
user$: Observable<{displayName: string, email: string}> = this.afAuth.authState.pipe(
switchMap(user => Boolean(user) ? this.afs.doc(`users/${user.id}`).valueChanges() : of(null))
);
...
}
Jednoducho povedané - this.afAuth.authState vydá objekt, ak je používateľ prihlásený. Ak používateľ nie je prihlásený, bude vrátená hodnota null. user$ vráti dáta dokumentu používateľa, ak je používateľ prihlásený. Ak používateľ neexistuje (t.j. authState=null), bude vrátená hodnota null.
