0

I'm building a website with angular.
The site contains a login page, and after the user logs in, there is a routing to the user's profile page, where data stored in Firebase should appear.

For some reason the data appears on the screen just after refreshing the page.
Do you have any idea what the reason is, and how I can fix the problem?

Thank you in advance!

Here is the relevant code in my opinion:

profile.component.html:

<h3 *ngFor="let item of user">Welcome back {{item.name}},</h3>
<h4>Your Details:</h4>
<table>
    <tbody *ngFor="let item of user">
        <div>
            <tr>
                <th>Name:</th>    
                <td>{{item.name}}</td>
            </tr>
            <tr>
                <th>Email:</th>   
                <td>{{item.email}}</td>
            </tr>
            <tr>
                <th>Phone Number:</th>   
                <td>{{item.phone}}</td>
            </tr>
        </div>
    </tbody> 
</table>

profile.component.ts:

import { Component, OnInit } from '@angular/core';
import {CrudService} from '../services/crud.service';
import { AuthService } from '../services/auth.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
  user: any;
  message = '';
  errorMessage = ''; 
  error: {name:string, message:string} = {name:'' , message:''}; //firebase error handle

  constructor(public authservice: AuthService, private router: Router,public crudservice:CrudService) { }

  ngOnInit(){
    if(this.authservice.currentUser != null)//We will make sure the user is logged in
    {
      this.crudservice.get_userInfo().subscribe(data => {
        this.user = data.map(c => {
          return {
            id: c.payload.doc.id,
            name: c.payload.doc.data()['name'],
            email: c.payload.doc.data()['email'],
            phone: c.payload.doc.data()['phone'],
          };
        })
        console.log(this.user);
      });  
    }
  }
}

auth.service.ts:

import { Injectable } from '@angular/core';
import { AngularFireAuth} from '@angular/fire/auth';
import {Router} from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  authState: any =null;
  constructor(private afu: AngularFireAuth, private router: Router) {
    this.afu.authState.subscribe((auth =>{
      this.authState = auth;
    }))
  }
  //get fanctions, to get data from firebase
  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{
    if((this.authState !== null) && (!this.isUserAnonymousLoggedIn)){
      return true
    } else{
      return false
    }
  } 
  //function in use in login.component.ts
  loginWithEmail(email: string, password: string){
    return this.afu.signInWithEmailAndPassword(email, password)
    .then((user) => {
      this.authState = user
    }).catch(error=>{
        console.log(error)
        throw error
      })
  }
}

crud.service.ts:

import { Injectable } from '@angular/core';
import { from } from 'rxjs';
import {AngularFirestore} from '@angular/fire/firestore';
import { AuthService } from '../services/auth.service';

@Injectable({
  providedIn: 'root'
})
export class CrudService {

  constructor(private authservice: AuthService, public fireservices:AngularFirestore) { }
  
  get_userInfo()
  {
    return this.fireservices.collection('users').doc(this.authservice.currentUserId).collection('user-info').snapshotChanges();
  }
}

login.component.ts:

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../services/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 handle
  error: {name:string, message:string} = {name:'' , message:''}; //firebase error handle

  constructor(private authservice: AuthService, private router: Router) { }
  
  ngOnInit(): void {
  }

  login()
  {
    this.clearErrorMessage();
    if(this.validateForm(this.email, this.password))
    {
      this.authservice.loginWithEmail(this.email, this.password)
      .then(() => {
        this.router.navigate(['/profile'])
      }).catch(_error =>{
        this.error = _error
        this.router.navigate(['/login'])
      })
    }  
  }

  clearErrorMessage()
  {
    this.errorMessage = '';
    this.error = {name: '', message:''};
  }

  validateForm(email, password)
  {
  .
  .
  .
  .
  }
}

1 Answer 1

1

That because subscribe in first return null or undefined.
To resolve this issue your code will be like :

  this.crudservice.get_userInfo().subscribe(data => {
         if(data != null && data != undefined) {
            this.user = data.map(c => {
              return {
                id: c.payload.doc.id,
                name: c.payload.doc.data()['name'],
                email: c.payload.doc.data()['email'],
                phone: c.payload.doc.data()['phone'],
              };
            })
            console.log(this.user); 
       }
     }

You can also add ngIf in your HTML page

<div *ngIf="user != null" >
<h3 *ngFor="let item of user">Welcome back {{item.name}},</h3>
<h4>Your Details:</h4>
<table>
    <tbody *ngFor="let item of user">
        <div>
            <tr>
                <th>Name:</th>    
                <td>{{item.name}}</td>
            </tr>
            <tr>
                <th>Email:</th>   
                <td>{{item.email}}</td>
            </tr>
            <tr>
                <th>Phone Number:</th>   
                <td>{{item.phone}}</td>
            </tr>
        </div>
    </tbody> 
</table>
</div>

More detail is here :

https://rxjs-dev.firebaseapp.com/guide/subscription
Hope useful

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you so much for your answer! I changed the code according to your recommendation, but I still need to refresh the page before the information loading. Could it be related to how I navigate the login page to the profile page? (I added the login.component.ts code to the question)
Do you have a hypothesis where could the problem be? @A.khalifa
I think this this.authservice.currentUser
Try to delete this code if(this.authservice.currentUser != null)//We will make sure the user is logged in
Thanks @A.khalifa , I deleted this line, but the problem still remains
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.