I'm working on my Angular project and I have this error where I'm not getting my authService.currentUserId that I use for searching in my firebase firestore collections, when I'm routing to pages for the first time after i login.
I have to refresh the page to get it to work and then i don't get the error again. This error does not occur when I use my registerWithEmail function and load the page but not with my loginWithEmail function.
import {Injectable} from '@angular/core';
import {AngularFireAuth} from '@angular/fire/auth';
import {Router} from '@angular/router';
import {AngularFirestore} from '@angular/fire/firestore';
import {CompanyUserInterface} from '../../models/companyuser';
@Injectable({
providedIn: 'root'
})
export class AuthService {
authState: any = null;
constructor(private afAuth: AngularFireAuth, private router: Router, public fireService: AngularFirestore) {
this.afAuth.authState.subscribe((auth => {
this.authState = auth;
}));
}
// is called when company register. creates firebase auth login with email and password
// this also creates a document with the information from the registration in the collection companies
registerWithEmail(email: string, password: string, companyUser: CompanyUserInterface) {
console.log(email, password);
return this.afAuth.createUserWithEmailAndPassword(email, password).then((data) => {
console.log('reg email', data);
this.authState = data;
// Gets user id and added to company for unique id
companyUser.UID = data.user.uid;
return this.fireService.collection('companies').add(Object.assign({}, companyUser));
}).catch(error => {
console.log(error);
throw error;
});
}
// is called in login and checks if login info is correct in firebase
loginWithEmail(email: string, password: string) {
return this.afAuth.signInWithEmailAndPassword(email, password).then((data) => {
this.authState = data;
})
.catch(error => {
console.log(error);
throw error;
});
}
logout(): void {
this.afAuth.signOut().then();
this.router.navigate(['/login']).then();
}
// all firebase getter functions
get isUserAnonymousLoggedIn(): boolean {
return (this.authState !== null) ? this.authState.isAnonymous : false;
}
get currentUserId(): string {
return (this.authState !== null) ? this.authState.uid : '';
}
get currentUserName(): string {
return this.authState.email;
}
get currentUser(): any {
return (this.authState !== null) ? this.authState : null;
}
get isUserEmailLoggedIn(): boolean {
return (this.authState !== null) && (!this.isUserAnonymousLoggedIn);
}
}
login.components.ts
import {Component, OnInit} from '@angular/core';
import {AuthService} from '../../services/auth/auth.service';
import {Router} from '@angular/router';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
email = '';
password = '';
errorMessage = ''; // validation error handling
error: { name: string, message: string } = {name: '', message: ''}; // for firebase error handling
constructor(private authService: AuthService, private router: Router) {
}
ngOnInit(): void {
}
// checks with firebase is user info is inputted and then if its valid. routes to userinfo site
login() {
this.clearErrorMessage();
if (this.validateForm(this.email, this.password)) {
this.authService.loginWithEmail(this.email, this.password).then(() => {
this.router.navigate(['schedule']).then();
}).catch(error => {
this.error = error;
this.router.navigate(['login']).then();
});
}
}
}
register.components.ts
import {Component, OnInit} from '@angular/core';
import {AuthService} from '../../services/auth/auth.service';
import {Router} from '@angular/router';
import {NgbModal, NgbModalConfig} from '@ng-bootstrap/ng-bootstrap';
import {CompanyUserInterface, CompanyUser} from '../../models/companyuser';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
companyUser: CompanyUserInterface;
password = '';
message = '';
errorMessage = ''; // validation error handling
error: { name: string, message: string } = {name: '', message: ''}; // for firebase error handling
constructor(public authService: AuthService,
private router: Router,
private config: NgbModalConfig,
private modalService: NgbModal,
) {
// customize default values of modals used by this component tree
config.backdrop = 'static';
config.keyboard = false;
this.companyUser = new CompanyUser('', '', '', '', '');
}
ngOnInit(): void {
}
// register company/association. checks if value are true before creating with authService
// sends company info from registry to create new doc in collection
registerWithEmail(content) {
this.clearErrorMessage();
console.log(this.companyUser);
if (this.validateRegisterForm(this.companyUser.email, this.password)) {
this.authService.registerWithEmail(this.companyUser.email, this.password, this.companyUser).then(() => {
this.modalService.open(content);
this.router.navigate(['userinfo']).then();
this.message = '\nCongratulations on creating your profile\n'.toUpperCase();
}).catch(error => {
this.error = error;
this.router.navigate(['register']).then();
});
}
}
}
schedule.service.ts
import {Injectable} from '@angular/core';
import {AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from '@angular/fire/firestore';
import {ScheduleInterface} from '../../models/schedule';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import {AuthService} from '../auth/auth.service';
@Injectable({
providedIn: 'root'
})
export class ScheduleService {
schedulesCollection: AngularFirestoreCollection<ScheduleInterface>;
schedules: Observable<ScheduleInterface[]>;
scheduleDoc: AngularFirestoreDocument<ScheduleInterface>;
constructor(private afs: AngularFirestore, public authService: AuthService) {
}
getSchedules(): Observable<ScheduleInterface[]> {
// I'm not getting my authService currentUserId on the first call.
console.log('test in getSchedules', this.authService.currentUserId);
return this.afs.collection('schedules', (ref) => ref
.where('UID', '==', this.authService.currentUserId)
.orderBy('user', 'asc'))
.snapshotChanges()
.pipe(
map((changes) =>
changes.map((a) => {
const data = a.payload.doc.data() as ScheduleInterface;
data.docRef = a.payload.doc.id;
return data;
})
)
);
}
}
