Search code examples
angularionic-frameworkfirebase-realtime-databaseangularfireangular-services

How to get data from Firebase to Service and then to Page correctly (Angularfire + ionic4)?


I am trying to get data from Firebase Realtimedatabase to my firebase.service via a function called getData() inside the firebase.service.

  • I can get the data inside the firebase.service but I can’t load them into mypage page.
  • I can see in the console that the data isn’t read from the Firebase when the page is loading, but afterwards.

Console log:

mypage.page.ts:16 undefined
firebase.service.ts:20 here is my data

How can I read my data only once and show them in my page? Using service?


mypage.page.ts code:

import { Component, OnInit } from '@angular/core';
import { FirebaseService } from '../firebase.service';

@Component({
  selector: 'app-mypage',
  templateUrl: './mypage.page.html',
  styleUrls: ['./mypage.page.scss'],
})
export class MypagePage implements OnInit {
  localData: string;

  constructor(private firebaseService: FirebaseService) {
    this.firebaseService.getData(); //Load data INTO the service

    this.localData = this.firebaseService.data;
    console.log(this.localData);
  }

  ngOnInit() {
  }

}

firebase.service.ts code:

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from '@angular/fire/compat/database';
import { DatabaseReference } from '@angular/fire/compat/database/interfaces';

@Injectable({
  providedIn: 'root'
})
export class FirebaseService {
  databaseRef: DatabaseReference;
  data: string;

  constructor(private db: AngularFireDatabase) {
    this.databaseRef = db.database.ref(); //Create databaseReference
  }

  getData(){
    this.databaseRef.child('data').get().then((snapshot) => {
      if (snapshot.exists()) {
        this.data = snapshot.val();
        console.log(this.data);
      } else {
        console.log('No data available');
      }
    });
  }
}

mypage.page.html code:

<ion-header>
  <ion-toolbar>
    <ion-title>mypage</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
<ion-label>{{ localData }}</ion-label>
</ion-content>

Solution

  • Usually, data is fetched asynchronously and your case is not an exception. The data won't be available until the promise completes, so the sensible thing to do in your case, is to return a Promise for the data from your service method:

      getData(): Promise<any> {
        return this.databaseRef.child('data').get().then((snapshot) => {
          if (snapshot.exists()) {
            // I don't think you need to keep the data in this.data anymore
            this.data = snapshot.val();
            console.log(this.data);
            return data;
          } else {
            console.log('No data available');
            return null; // or return another default value, like [] or {} or "";
          }
        });
      }
    

    In your component, you can get the data like this:

    export class MypagePage implements OnInit {
      localData: string;
    
      constructor(private firebaseService: FirebaseService) {}
    
      ngOnInit() {
        this.firebaseService.getData().then(data => {
           this.localData = data;
        });
      }
    
    }