Making a Website Using Ionic & Firebase Hosting

So I recently accomplished making a website using Ionic3 ( for my company. I’d like to give a big shoutout to all the Ionic developers for this amazing framework. Anyway, here’s how I did it:

1: Make an Ionic 3 project directory. You can find out how almost anywhere.

2: Run ionic serve (Using Ionic-lab would be futile)

3: Make a separate directory using the firebase-cli command: firebase serve

4: Ionic serve makes a folder in your Ionic Project Directory’s /www called: build.
Copy build (and assets if needed).
<img src="//" width=600" height=“300”>

5: Paste them into your firebase directory public folder.

You may also want to copy over your index.html for SEO and website meta data.

5: Run firebase deploy in your Firebase project directory and you should be able to see your progress in your hosting site URL.

Making URLS

2: Now, in Ionic 3 lazy loading, it actually makes a URL for every page with the @IonicPage decorator. You can modify this URL using the segment in @IonicPage object

  segment : "new-assignment"
  selector: 'page-new-assignment',
  templateUrl: 'new-assignment.html',
export class NewAssignment {
    public navCtrl: NavController, 
    public navParams: NavParams) {}

3: For pages that are details for items or whatnot…

  // defaultHistory: ["HomePage"],
  segment: 'assignments/:sbaid/drive&=sdk/:timestamp',
  selector: 'assignment-content',
  templateUrl: 'assignment-content.html',
export class AssignmentContent {
    public navCtrl: NavController, 
    public navParams: NavParams) {}

Connecting to Domain

I bought my domain from . Google all the way.
The process of connecting your Firebase Hosting Site to your domain is quite easy. The domain info screen should have a DNS configuration section at the bottom. Firebase Hosting will give you the 2 DNS config numbers in which you input into your Site Config.

Detailed explanation:

Extra Resources I used


Code to find out if an ID/Item exists in Firebase database:
Taken from:

My modifications in my project:

  // defaultHistory: ["HomePage"],
  segment: 'assignments/:sbaid/drive&=sdk/:timestamp',
  selector: 'assignment-content',
  templateUrl: 'assignment-content.html',
export class AssignmentContent {
    public navCtrl: NavController, 
    public navParams: NavParams) {


  this.eventsdata.getrequestDetail( this.navParams.get('sbaid')).once('value', ((snapshot)=> {
     var exists = (snapshot.val() !== null);
     this.AssignmentExistsCallback(   this.navParams.get('sbaid') , exists);

AssignmentExistsCallback(sbaId, exists) {
  if (exists) { = true
    this.Sbaiid = sbaId


  } else {
  this.veryCustomShowAlert("Whoops 🛫","Sorry, the assignment you requested does not exist", "Ok","Cancel")



getrequestDetail(aid): any {
    return this.sbaList.child(aid);

Example: This URL contains an ID that does not exist in my Firebase database. Observe how the code handles it:


Code to center items on page and applies padding where needed to improve website UX
(Taken from the Ionic 3 conference app)


  .innercontent-padding ion-card-header .item {
    padding: 4px 30px;

  .innercontent-padding ion-card-header,
  .innercontent-padding ion-card-content,
  .innercontent-padding ion-card-content .list ion-item-content, {
    padding: 0;

  @media (min-width: 600px) {
    .innercontent-padding {
      width: 60%;
      margin: 23px auto;

Usage anypage.html

     <ion-header >
<ion-content  class="outer-content speaker-list">

<ion-card class="innercontent-padding"  text-wrap>



(Taken from Ionic 3 Conference app: list of speakers page)

  • Hints and Important Notes

My firebase database version is 3.7.5

Modals do not load when a @IonicPage decorator is attached so use the “app.module.ts” to initialize them.

Thank you! I hope to see more websites made with Ionic soon! If there are any suggestions or questions, proceed to the comments below.


Looks awesome! That’s the power of Ionic :slight_smile:

One question, how did you code the special footer area with all the links? Is it inside an ion-footer or some special component you created? Thanks!


@saimon Looks like a custom component, called global-footer. It’s inside ion-content with the rest of the stuff.

1 Like

Thanks for sharing. One comment: Instead of ionic serve I suggest you use npm run build --prod to build your www folder. This runs a production build and makes the files in www/build much smaller.


Never thought of this, Thank you.

Yeah as @ihadeed said, I used a component called global footer.

Here’s the code (Remember to change it):


<!-- Generated template for the GlobalFooter component -->
 <div style="padding: 80px"></div>
<div padding class="outer-content speaker-list darkback">

  <div class="speaker-card">



              <h6  (click)="openPage('NewAssignment')"> New Assignment </h6>
              <h6 (click)="openPage('AssignmentEnter')"> Existing Assignment </h6>
              <h6 (click)="open('')"> Download on Device </h6>
              <h6 (click)="openPage('Services')"> Services </h6>
              <h6 (click)="open('')"> Jobs </h6>




              <h6 (click)="openPage('PublicCommunity')"> Join Public Community </h6>
              <h6 (click)="openPage('TeacherCommunity')"> Join Teachers Community </h6>
              <h6 (click)="open('')"> Facebook </h6>
              <h6 (click)="open('')"> Instagram </h6>
              <h6 (click)="open('')"> Email </h6>



              <h6 (click)="open('')"> Company Policy </h6>
              <h6 (click)="open('')"> Privacy Policy </h6>
              <h6 (click)="open('')"> Supported Subjects & Resources </h6>
              <h6 (click)="openPage('About')"> About </h6>
              <h6 (click)="openPage('Faq')"> FAQ </h6>
              <h6 (click)="openPage('Members')"> PJaguar Team Members </h6>


<p text-center padding>
Copyright © 2017 Project Jaguar Inc. || All Rights Reserved



import { Component } from '@angular/core';
import {
  NavController, Events, NavParams, ModalController, ViewController, Content,
  ActionSheetController, AlertController, ToastController,MenuController
} from 'ionic-angular';
 * Generated class for the GlobalFooter component.
 * See
 * for more info on Angular Components.
  selector: 'global-footer',
  templateUrl: 'global-footer.html'
export class GlobalFooter {

  text: string;

   public nav: NavController
  ) {

    console.log('Hello GlobalFooter Component');
    this.text = 'Hello World';





And to Import it into a page, I import it into the page module (IonicPage decorator needed)

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { Page } from './page';
import { GlobalFooterModule } from '../../components/global-header/global-header.module';

  declarations: [
  imports: [
  exports: [
export class PageModule {}

and finally, showing it in the Page.html

<global-footer> </global-footer>

Does anyone know why the “/#” shows after the root URL?

I am trying to figure out this one. However, it is related to Angular 4 and not directly to Ionic 3.

If you are wondering about SEO in your Ionic website, you can use the following:

import { Meta, Title } from "@angular/platform-browser";

constructor(meta: Meta, title: Title) {

    title.setTitle('Title of the page');

    meta.addTags ( [
      { name: 'author',   content: 'Author's name'},
      { name: 'keywords', content: 'keyword 1, keyword 2......'},
      { name: 'description', content: 'Description of the page' }
    ] );


How could I upload images with this website ?! @trevaun23 @saimon

I have a problem. The command "ionic cordova build android didn’t worked correctly. What can i do…

@trevaun23 @saimon @ihadeed
I’m building a website with ionic . I push data with navCtrl to another page and every thing is working as expected . I get the params form constructor . the problem is when I refresh this page with browser not from ionic app , I get error ‘undefined id for my collection in database’ that’s a result of no params any more . how could I solve this problem ? thanks in advance :slight_smile:

Hey! Apologies for my late reply but I hope this code answers your question:

Since I cant use the Ionic Plugins for uploading images, I use this:

npm install ng2-file-input

in page.module.ts
import { Ng2FileInputModule } from 'ng2-file-input';
in page.html

 <ion-item  >
      <ng2-file-input   [browse-text]="'Drop your files here'" [drop-text]="'📁 <br><br>'" [remove-text]="'Off you go'" [id]="'multiFilesInputWithPreview'" (onCouldNotRemove)="onCouldNotRemove($event)" [multiple]="true"  (onRemoved)="onRemoved($event)" (onAdded)="onAdded($event)" (onAction)="onAction($event)"></ng2-file-input>

in page.ts (Imports)
import { Ng2FileInputService, Ng2FileInputAction } from 'ng2-file-input';

in page.ts (Variable Declaration)

myFileInputIdentifier:string = "multiFilesInputWithPreview";
  public actionLog:string="";

in page.ts (Constructor)

    public ng2FileInputService: Ng2FileInputService,

in page.ts (Main)

public onAction(event: any){
    this.actionLog += "\n currentFiles: " + this.getFileNames(event.currentFiles);
   // console.log(this.actionLog);

  public onAdded(event: any){
    this.actionLog += "\n FileInput: "+event;
    this.actionLog += "\n Action: File added";
   //   let filename = this.eventData.getfilename(fileentry);
   //     let fileext = this.eventData.getfileext(fileentry);
  public onRemoved(event: any){
    this.actionLog += "\n FileInput: ";
    this.actionLog += "\n Action: File removed";
  public onInvalidDenied(event: any){
    this.actionLog += "\n FileInput: ";
    this.actionLog += "\n Action: File denied";
  public onCouldNotRemove(event: any){
    this.actionLog += "\n FileInput: ";
    this.actionLog += "\n Action: Could not remove file";
  resetFileInput() {
    let files=this.ng2FileInputService.getCurrentFiles(this.myFileInputIdentifier);
    this.actionLog += "\n The currently added files are: " + this.getFileNames(files);
    let names=files.forEach((file) => {
        var reader = new FileReader();
       let filedata =  reader.readAsDataURL(file)

        var reader = new FileReader();
        reader.onload = (function(theFile){
          var fileName =;
          return function(e){
    //return names ? names.join(", "): "No files currently added.";


To get the Files:

You can see this in action here:

I used to have this problem because of the lifecycle hooks.

Instead of using ngOnInit() or the constructor to process the params, I use:

//code with id

Instead of using ionViewWillEnter(), I use:

//code with id

@trevaun23 thanks for your answer . I have watched vedio on youtube use input type file for implementing the uploading . what do you think of this way ?

I tried that too. Longer process. (I’m a lazy programmer, I go for the easiest and asthetically pleasing solution)

1 Like

In ng2-file-input docs they say that i should install bootstrap . so how did you install it ?

I didn’t put in bootstrap until a few weeks after adding in the file input. But you can use the CDN to get bootstrap.

1 Like

A vote of thanks :slight_smile:

no errors appears if the file is not in my extensions … what I should do ?

@Morad-Abdo did you get this to work with the method that @trevaun23 proposed i.e using ngAfterViewInit() and ionViewWillEnter() ? I’m looking into this area at the moment and keen to know the best way to go. Thanks!