Category: ionic

How to combine tab navigation with side menu in Ionic

menu banner

With ionic CLI you can quickly and easy create a Side Menu app just by running the command

ionic start sidemenu

or create a tab application by running:

ionic start tab

Those are common navigation patterns used by a lot of mobile applications today:

In this short tutorial we are going to try to combine those different navigation patterns into one application.

We will keep things simple, we are going to make the transition from a login page (Taken from ionappFull4Pro starter) to our inside navigation, which combines side menu and tabs.

Login workflow

This is a module that is part of the ionappFull4Pro starter, and with it you’ll be able to:
– Login with Firebase username and password
– Login with Google (native) //for this the app must run on a device or an emulator
– Login with Facebook (native) //for this the app must run on a device or an emulator
– Login with Google (PWA mode) //this mean that you can login with google running the app on the browser
– Recover your password
– Register new user
– User editable profile

Prerequisites

We assume you are familiar with ionic, and you have set up your ionic environment, if not you can follow this tutorial: https://ionicframework.com/getting-started#cli

We are going to start creating a blank ionic template using the CLI commandand then we are going to create all the needed pages:

ionic start convinedNavigation blank
ionic g page menu
ionic g page tabs
ionic g page tab1
ionic g page tab2

Spoiler alert

We are going to use lazy loading, for load our pages, so after create the new project feel free to remove the home page generated by default.

Now use your favorite IDE to open the project (mine is Microsoft Code) and change the rootPage variable to a string “LoginPwaPage”, this will tells ionic LoginPwaPage is the entry point page.

ionic app component

Lest import the login component from ionappFull4Pro into our project. First, copy the login-workflow folder (which contains login, profile,recover and register pages) into our project (also you can follow the instructions on the instructions.txt file included in the folder).

import login from ionappfull4pro

This is how it should looks like:

login workflow in our local project

Follow the instructions on the instructions.txt file to complete the import of this component:

Instructions.txt

Instructions to import this component in your existing ionic app.

If you don't have an ionic app created, create one, by running the following command on the command console, on the folder you want your app to be created, 
once your app is created locate the pages folder and copy this component (folder) in the page folder:

$ ionic start MyAppName blank

for more info go to the ionic official documentation.


Once you have your app created Install the components dependencies (see what is imported on the ts files on this component):

On your firebase dashboard enable the email/password methods, see documentation: http://jomendez.com/ionAppFull4Pro-documentation/#!/firebase_configuration
	
Notes:
For this component to work you need to setup firebase and also import the DatabaseProvider from "/providers/database/database" included on the ionAppFull4Pro project.
Also import /providers/auth-data provided from ionAppFull4Pro to your app
Also copy src/config/config.ts from this project (ionAppFull4Pro) to your application, and enter your firebase information.

Remember to install the firebase dependencies and add the providers to the app.module.ts file:

npm i --save angularfire2 firebase

For this tutorial we are going to use the login-pwa component to keep it simple and be able to test the app in the browser without having to run it on a device or emulator. Login pwa component uses some “fancy” animation library called VegasJs (this is not required for the login component to work, you can easily remove it). In order to include it and make it work you’ll need to copy few thinks from ionappFull4Pro starter, first include the jquery library and vegas dependencies on index.thml and then copy the files into assets folder:

add jquery and vega index
images on the assets folder

This is how the app.modules should looks like after all the imports and declaration:

app modules dependencies

One last thing it we have to redirect to menu page after login, so we will have to modify the login() method, lets comment the code that redirects to the profile page and add the code that set the MenuPage as the root:

redirect to menupage

Build the menu navigation:

Add this menu code to your src/pages/menu/menu.html


<ion-menu [content]="content">
  <ion-header>
    <ion-toolbar>
      <ion-title>Menu</ion-title>
    </ion-toolbar>
  </ion-header>
 
  <ion-content>
    <ion-list>
      <button ion-item menuClose *ngFor="let p of pages" (click)="openPage(p)">
          <ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
          {{ p.title }}
        </button>
    </ion-list>
  </ion-content>
</ion-menu>
 
<!-- main navigation -->
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>

Add this code to src/pages/menu/menu.ts
Notice that in page one of the pages that can be called is the Profile page that comes with the login component from ionappFull4Pro starter

 pages = [
    { title: 'Tab 1', pageName: 'TabsPage', tabComponent: 'Tab1Page', index: 0, icon: 'home' },
    { title: 'Tab 2', pageName: 'TabsPage', tabComponent: 'Tab2Page', index: 1, icon: 'shuffle' },
    { title: 'Profile', pageName: 'AfterLoginPage', icon: 'contacts' },,//notice we cal here the Profile that comes with the login workflow component on ionAppFull4Pro starter
  ];
import { Tab2Page } from './../tab2/tab2';
import { Tab1Page } from './../tab1/tab1';
import { TabsPage } from './../tabs/tabs';
import { Component, ViewChild } from '@angular/core';
import { IonicPage, NavController, Nav } from 'ionic-angular';
 

@IonicPage()
@Component({
  selector: 'page-menu',
  templateUrl: 'menu.html',
})
export class MenuPage {
  // Basic root for our content view
  rootPage = 'TabsPage';
 
  // Reference to the app's root nav
  @ViewChild(Nav) nav: Nav;
 
  pages = [
    { title: 'Tab 1', pageName: 'TabsPage', tabComponent: 'Tab1Page', index: 0, icon: 'home' },
    { title: 'Tab 2', pageName: 'TabsPage', tabComponent: 'Tab2Page', index: 1, icon: 'shuffle' },
    { title: 'Profile', pageName: 'AfterLoginPage', icon: 'contacts' },
  ];

  constructor(public navCtrl: NavController) { }
 
  openPage(page) {
    let params = {};
 
    // The index is equal to the order of our tabs inside tabs.ts
    if (page.index) {
      params = { tabIndex: page.index };
    }
 
    // The active child nav is our Tabs Navigation
    if (this.nav.getActiveChildNav() && page.index != undefined) {
      this.nav.getActiveChildNav().select(page.index);
    } else {
      // Tabs are not active, so reset the root page 
      // In this case: moving to or from SpecialPage
      this.nav.setRoot(page.pageName, params);
    }
  }
 
  isActive(page) {
    
    let childNav = this.nav.getActiveChildNav();
 
    if (childNav) {
      if (childNav.getSelected() && childNav.getSelected().root === page.tabComponent) {
        return 'primary';
      }
      return;
    }
 
    // Fallback needed when there is no active childnav (tabs not active)
    if (this.nav.getActive() && this.nav.getActive().name === page.pageName) {
      return 'primary';
    }
    return;
  }
 
}


Adding the Tab

Open your src/pages/tabs/tabs.html and change it to:

<ion-tabs [selectedIndex]="myIndex">
  <ion-tab [root]="tab1Root" tabTitle="Tab 1" tabIcon="home"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="Tab 2" tabIcon="contacts"></ion-tab>
</ion-tabs>

This tab bar will be pointing to the 2 tabs pages we created at the beginning.
Now change your src/pages/tabs/tabs.ts

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
 
@IonicPage()
@Component({
  selector: 'page-tabs',
  templateUrl: 'tabs.html',
})
export class TabsPage {
 
  tab1Root: any = 'Tab1Page';
  tab2Root: any = 'Tab2Page';
  myIndex: number;
 
  constructor(navParams: NavParams) {
    // Set the active tab based on the passed index from menu.ts
    this.myIndex = navParams.data.tabIndex || 0;
  }
}

Now we only need to add a menu button to all of our pages so we can toggle the menu from everywhere. Go through these 2 files (tab1, tab2) and change it, add the following html code:

Tab1

<ion-header>
  <ion-navbar>
      <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>Tab1</ion-title>
  </ion-navbar>
</ion-header>
 
<ion-content padding>
  This is tab 1 content
</ion-content>

Tab2

<ion-header>
  <ion-navbar>
      <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>Tab2</ion-title>
  </ion-navbar>
</ion-header>
 
<ion-content padding>
  This is tab 2 content
</ion-content>

This is the result:

Try it yourself:

Conclusions

With this article we got two navigation pattern working together, it could be a little bit tricky, but it is possible, also we were able to integrate/import the login module very easy, from the ionAppFull4Pro ionic starter into our applications, saving us a lot of time and development effort, and just with that we were able to implement an app with firebase login, google login, recover password, register user, and profile page.

Cheers,
Jose

How To Debug White Screen Ionic error on devices

How To Debug White Screen Ionic error on devices

Debug White Screen Ionic error on devices

This type of error occurs when your Ionic app is working fine in your desktop browser (ionic serve) and then you deploy it to a device or emulator and it doesn’t work at all! What you see is a white screen when you open the app.
It is easy to debug your ionic app when doing `ionic serve` you just open the browser’s console, but once you deploy to a device or emulator, it is easy to know what is causing the error since the device doesn’t have a console to see JavaScript errors.

There are two ways to figure out what is happening one is using the cli livereload with consolelogs when using run or emulate command, and the second one is using the chrome developer tool.

Ionic livereload with consolelogs

note:
You can only use –consolelogs if you also use –livereload.

The –livereload option will instantly reload/update the app on your device or emulator it is similar to when you run ionic serve for testing your app on the desktop browser, the –consolelogs will log on the cmd console all the JavaScript error, etc. providing feedback of what is happening.

ionic run android --livereload --consolelogs

You can use the shorthand version:

ionic run android -l -c

Chrome Developer Tool

You need to configure your device to enable developer mode. For more information go here: https://developers.google.com/web/tools/chrome-devtools/remote-debugging/

Now you need to run your app on an Android device, you can attach the Chrome Developer Tools to the app and see the error in the Console, you need to connect your device with a USB cable to your computer, open your desktop Chrome browser and type chrome://inspect on the address bar.

You should see your device listed, click on inspect and from there you can use the Developer Tools the same way you use it for your desktop browser when do ionic serve. You should see the error causing the white screen, and any other relevant information like the console.log() that you placed on your ionic app code.

This doesn’t work for iOS and Safari web inspector, the most universal way is to use the –livereload option, which will work for both iOS and Android.

Happy Coding,
Cheers

Add to Home Screen your ionic PWA

Add to Home Screen your ionic PWA

add-to-home-screen

One of the feature of Progressive Web Apps is the ability to add to home screen your application, in a mobile phone or on a desktop computer, if using Chrome (recommended) it handles most of the heavy lifting for you, and on Android, Chrome will generate a WebAPK creating an even more integrated experience for your users.

Starting on Chrome 68 (beta in early June 2018), Chrome will not automatically show the Add to Home Screen banner, instead, you must show it by calling prompt() on the beforeinstallprompt event.

Criteria to fire the “beforeinstallprompt” event

– The web app is not already installed
– Meets a user engagement heuristic (currently, the user has interacted with the domain for at least 30 seconds)
– Includes a web app manifest that includes:
   short_name or name
   icons must include a 192px and a 512px sized icons
   start_url
   display must be one of: fullscreen, standalone, or minimal-ui
– Served over HTTPS (required for service workers)
– Has registered a service worker with a fetch event handler

Note: Other browsers may have different criteria to trigger the beforeinstallprompt event, check their respective sites for full details: Edge, Firefox, Opera.

Show the add to home screen prompt

In order to prompt to the users the Add to Home Screen prompt, you need to:

1- Listen for the beforeinstallprompt event
2- Notify the user your app can be installed with a button or other element that will generate a user gesture event.
3- Show the prompt by calling prompt() on the saved beforeinstallprompt event.

let deferredPrompt;

window.addEventListener('beforeinstallprompt', (e) => {
  // Prevent Chrome 67 and earlier from automatically showing the prompt
  e.preventDefault();
  // Stash the event so it can be triggered later on the button event.
  deferredPrompt = e;
// Update UI by showing a button to notify the user they can add to home screen
  btn.style.display = 'block';
});

//button click event to show the promt
btn.addEventListener('click', (e) => {
  // hide our user interface that shows our button
  btn.style.display = 'none';
  // Show the prompt
  deferredPrompt.prompt();
  // Wait for the user to respond to the prompt
  deferredPrompt.userChoice
    .then((choiceResult) => {
      if (choiceResult.outcome === 'accepted') {
        console.log('User accepted the prompt');
      } else {
        console.log('User dismissed the prompt');
      }
      deferredPrompt = null;
    });
});

You can only call deferredPrompt.prompt() on the deferred event once, if the user dismissed it, you’ll need to wait until the beforeinstallprompt event is fired on the next page navigation.

How to determine if the app was installed

To determine if the application was successfully added to the user’s home screen once they accepted the prompt, you need to listen for the appinstalled event.

window.addEventListener('appinstalled', (event) => {
 console.log('installed');
});

Detecting with JavaScript if you app is launched from the home screen

if (window.matchMedia('(display-mode: standalone)').matches) {
  console.log('display-mode is standalone');
}

Safari

if (window.navigator.standalone === true) {
  console.log('display-mode is standalone');
}

Easiest way to test if the beforeinstallprompt event will be fired

Easiest way is to use Lighthouse to audit your app, and check the results of the User Can Be Prompted To Install The Web App test.

Practical example with ionic

For this example I going to use ionic, we are going to generate a PWA with ionic, for this example I assume you are familiar with ionic and you have installed it on your computer, if not, then you can read the here

Lets generate our ionic app:

After you create the ionic blank app, lets run ionic serve:

cd pwa
ionic serve

You should see something like this on your browser:

Open your application using google chrome, open the dev tool, go to audit and run the Progressive web app audit:

You’ll notice that the app is only 45% PWA out of the box, we should make some changes first to comply with the requirements to trigger the beforeinstallprompt event:

Registering the service worker

Open the ionic app on your preferred IDE (I’ll use Microsoft code) and go to ./src/index.html and uncomment this line:

<!-- un-comment this code to enable service worker
  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('service-worker.js')
        .then(() => console.log('service worker installed'))
        .catch(err => console.error('Error', err));
    }
  </script>-->

The another requirement is to have a manifest.json, fortunately ionic generates one for us:

{
  "name": "Ionic",
  "short_name": "Ionic",
  "start_url": "index.html",
  "display": "standalone",
  "icons": [{
    "src": "assets/imgs/logo.png",
    "sizes": "512x512",
    "type": "image/png"
  }],
  "background_color": "#4e8ef7",
  "theme_color": "#4e8ef7"
}

Now lets provide a fallback when JavaScript is not available by just adding a < noscript > tag on the index:

<noscript>
This application needs JavaScript to work, please enable JavaScript on your browser
</noscript>

With just that, we were able to go from 45 to 82:

Now we need to deploy our app to firebase hosting to be able to have HTTPS, and a 100 score on the lighthouse.

Install firebase tools

npm install -g firebase-tools

Initialize your site

$ firebase init

To deploy your site, run the following command from your project’s root directory:

$ firebase deploy

For more info go to https://firebase.google.com/docs/hosting/deploying

Now you can sun the lighthouse tool and obtain a 100 score:

Capturing the event

Go back to the ionic app code, locate the pages folder on src/pages/home and edit the home.html and home.ts as follow:

home.html

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  The world is your oyster.
  <p>
    If you get lost, the <a href="http://ionicframework.com/docs/v2">docs</a> will be your guide.
  </p>
  <button class="btn" ion-button full (click)="add_to_home(event)" *ngIf="showBtn" >Install</button>
</ion-content>

home.ts

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  showBtn: boolean = false;
  deferredPrompt;
  constructor(public navCtrl: NavController) {
    
  }

  ionViewWillEnter(){
    window.addEventListener('beforeinstallprompt', (e) => {
      // Prevent Chrome 67 and earlier from automatically showing the prompt
      e.preventDefault();
      // Stash the event so it can be triggered later on the button event.
      this.deferredPrompt = e;
      
    // Update UI by showing a button to notify the user they can add to home screen
      this.showBtn = true;
    });
    
    //button click event to show the promt
            
    window.addEventListener('appinstalled', (event) => {
     alert('installed');
    });
    
    
    if (window.matchMedia('(display-mode: standalone)').matches) {
      alert('display-mode is standalone');
    }
  }

  add_to_home(e){
    debugger
    // hide our user interface that shows our button
    // Show the prompt
    this.deferredPrompt.prompt();
    // Wait for the user to respond to the prompt
    this.deferredPrompt.userChoice
      .then((choiceResult) => {
        if (choiceResult.outcome === 'accepted') {
          alert('User accepted the prompt');
        } else {
          alert('User dismissed the prompt');
        }
        this.deferredPrompt = null;
      });
  };

}

Test in your browser

To test the functionality, we could make some changes on chrome to force to trigger the event (taken from here https://stackoverflow.com/a/50626433/4320602)

For security reasons, as others have written as well, browsers don’t allow you to manually trigger the install event.

However, there is a way you can test it yourself. Go to chrome://flags and enable “Bypass user engagement checks”

This will kick off the prompt so you can test.

now run your app and click on the install button, you should see something like this:

Now the app will run as standalone app:

Happy coding,
Cheers

ionShopping

ionShopping is a intuitive, clean and professional hybrid app, perfect for e-commerce, online shopping, etc. It is a completely functional template/starter for ionic developers to create a multi-platform shopping app with shopping cart, custom powerful push notifications, and a custom Admin panel to manage the orders, the list of products, the images, etc.

What am I getting?

When you download ionShopping you’ll obtain the source code of the ionic app and the angular dashboard admin panel, plus an awesome documentation that will walk you through the setup process, step by step, the firebase setup, the setup of the environment, etc. The process should be smooth, but if you encounter any issue with the setup of the project, it will be my pleasure to assist you via email, my email is on the documentation.

Features:

ionic app:
– Login (with email/pass and social login with facebook and google plus)
– Recover password
– Sign up
– Tabs system to provide a more clean experience to the user
– Product list (manageable from the admin panel)
– Items details section
– Awesome order system/Shopping cart + checkout with paypal integrated
– Call number native and send SMS from the landing page to contact the store
– Push notifications (with custom dashboard) for promotions with promo landing page
– Editable profile

Admin dashboard:
– Manage all the items, details, images, prices, etc from the amazing custom admin panel included
– Tracking Order (shopping cart), from the admin panel you’ll see and manage the status of the order (purchased, processing, delivered).
– Powerful and custom Push Notification system to send notifications to user with rich text and images, to inform or promote offers discounts, etc. You can run a promotion from an start date to an end date, you can also create and save notification to be sent in the future
– Technologies used on the dashboard: Angular 4, Cloud firestore

Ionic App screenshots










Admin dashboard demo

The admin dashboard source code is included with the ionic code

Try before you invest

Note:
The notification and the social login will only work on an emulator or a cellphone

Get it from here:
https://market.ionicframework.com/starters/ionshopping/

ionRestaurant

ionRestaurant is a intuitive, clean and professional hybrid app, perfect for Restaurant, Bar, Bakery, etc. It is a completely functional template/starter for ionic developers to create a multi-platform restaurant app with food ordering system (shopping cart), custom powerful push notifications, and a custom Admin panel to manage the orders, the menu, the images, etc.

What am I getting?

When you download ionRestaurant you’ll obtain the source code of the ionic app and the angular dashboard admin panel, plus an awesome documentation that will walk you through the all setup process, step by step, the firebase setup and the setup of the environment, etc. The process should be smooth, but if you encounter any issue with the setup of the project, it will be my pleasure to assist you, my email is on the documentation.

Features:

ionic app:
– Login (with email/pass and social login with facebook and google plus)
– Recover password
– Sign up
– Tabs system to provide a more clean experience to the user
– Restaurant Menu (manageable from the admin panel)
– Items details section
– Awesome order system/Shopping cart + checkout with paypal integrated
– About us + contact section (With maps, gps, call number native)
– Push notifications for promotions with promo landing page
– Profile editable

Admin dashboard:
– Manage all the menu, images, plates, prices, etc from the amazing custom admin panel included
– Tracking Order (shopping cart), from the admin panel you’ll see and manage the status of the order (purchased, processing, delivered).
– Powerful and custom Push Notification system to send notifications to user with rich text and images, to inform or promote offers discounts, etc. You can run a promotion from an start date to an end date, you can also create and save notification to be sent in the future
– Technologies used on the dashboard: Angular 4, Cloud firestore

Ionic App screenshots

Admin panel screenshots

Try before you invest

Note:
The notification and the social login will only work on an emulator or a cellphone

Get it from here:
https://market.ionicframework.com/starters/ionrestaurant

ionPushemPro

You can use this starter to create your application on top of it and send and receive notifications with your own admin dashboard backend.
If you are a freelance developer, you can offer the dashboard backend to your clients as a plus, when you develop applications like e-commerce, for restaurants, anything where you need to communicate to the users about new features, products, promotions, etc.

The admin backend source code is included with this starter

With this starter you will be able to:

  • Send notifications to individual users
  • Create user groups and send notifications to group of users
  • Create channels/topics for the ionic user to opt-in/out and receive notifications via channesl
  • There is an option for the ionic user to create local notification (this is a generic functionality you should adapt it to your own needs)
  • Firebase and social login (google and facebook) with the ability to update the user’s profile

Watch the following video for more info:

Live ionic demo

Note:
The notification and the social login will only work on an emulator or a cellphone

Get it from here:
https://market.ionicframework.com/starters/ionpushempro

Ionic CRUD Application with Cloud Firestore

Ionic CRUD Application with Cloud Firestore

ionic crud
In this tutorial we are going to create the most simplest ionic CRUD(Create, Read, Update and Delete) using Cloud firestore.

At the end of this tutorial you’ll be able to:
-Setup a firebase account.
-Configure firestore database permissions.
-Create an ionic app using ionic cli (command line tool).
-Create, Read, Update and Delete to a firestore database from an ionic app.

What is cloud firestore?

Lets set up a firebase account.

Go to https://console.firebase.google.com and login with your google account or create one.

Enter the name of the project and click on Add Firebase to your web app.

We are going to use this data later, this will allow us to connect to firebase.

Next step is to configure Cloud Firestore, follow the following steps in the image, and start in test mode for now, to keep it simple.

For more rules you can visit here: https://cloud.google.com/firestore/docs/security/rules-query

Before we get into the ionic part, lets see how a firestore database structure looks like:

This example was taken from the ionAppFull4Pro ionic starter.
In this example you can see that the firestore data model is based on collections and documents, and you can nest collection within documents:

for more details you can visit here https://firebase.google.com/docs/firestore/data-model.

Lets create the ionic CRUD project.

First, install Node.js. Then, install the latest Cordova and Ionic command-line tools in your terminal. Follow the Android and iOS platform guides to install required tools for development. For more info go here: https://ionicframework.com/getting-started.

npm install -g cordova ionic

Now lets create the ionic app

ionic start crud blank

When the cli finish to create the files, do:

 > cd crud
 > ionic serve

To go to the new folder created, then run “ionic serve” to make sure that everything when correctly. This is how it should looks like:

Now, open the source code on your favorite editor, I prefer VS code. The source code should look like this:

Run the following command to install firebase dependency:

npm install firebase --save

We need to configure firebase on our app, for this we are going to need the config variable from previous step.

  var config = {
    apiKey: "<your key>",
    authDomain: "<your key>",
    databaseURL: "<your key>",
    projectId: "<your key>",
    storageBucket: "<your key>",
    messagingSenderId: "<your key>"
  };
firebase.initializeApp(config);

Insert the config variable on the app.module.ts for that lets add the firebase dependency.

...
import * as firebase from 'firebase';

const config = {
  apiKey: "<your key>",
  authDomain: "<your key>",
  databaseURL: "<your key>",
  projectId: "<your key>",
  storageBucket: "<your key>",
  messagingSenderId: "<your key>"
};
firebase.initializeApp(config);

...

Go to the home.html and insert this code.

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Crud example
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
<ion-list>
    <ion-item>
        <ion-label floating>Message title :</ion-label>
        <ion-input type="text" value="" [(ngModel)]="model.title"></ion-input>
      </ion-item>            
      <ion-item>
        <ion-label floating>Message body :</ion-label>
        <ion-textarea   type="text" row="10" [(ngModel)]="model.text"></ion-textarea>
      </ion-item>
      <ion-item>
          <button type="button" (click)="addMessage()" ion-button full >Submit</button>
      </ion-item>
</ion-list>

  <ion-card>
    <ion-card-header>
      Swipe item to the left to delete or edit
    </ion-card-header>
  </ion-card>
  <ion-list>
    <ion-item-sliding *ngFor="let message of messages">
      <ion-item>
        <h3>title: {{message.title}}</h3>
        <p>body: {{message.text}}</p>
      </ion-item>
      <ion-item-options>
        <button ion-button color="danger" (click)="deleteMessage(message.$key)">
        <ion-icon name="ios-trash"></ion-icon>
        delete
      </button>
      <button ion-button color="success" (click)="updateMessage(message)">
          <ion-icon name="ios-create"></ion-icon>
          edit
        </button>
      </ion-item-options>
    </ion-item-sliding>
  </ion-list>

</ion-content>

We are using an *ngFor to generate all the items on the list, we are creating sliding items so we can set a button to delete the item.

We need to add the methods for the ionic CRUD operation (got it from the ionAppFull4Pro project).

  getAllDocuments(collection: string): Promise<any> {
    return new Promise((resolve, reject) => {
        this.db.collection(collection)
            .get()
            .then((querySnapshot) => {
                let arr = [];
                querySnapshot.forEach(function (doc) {
                    var obj = JSON.parse(JSON.stringify(doc.data()));
                    obj.$key = doc.id
                    console.log(obj)
                    arr.push(obj);
                });

                if (arr.length > 0) {
                    console.log("Document data:", arr);
                    resolve(arr);
                } else {
                    console.log("No such document!");
                    resolve(null);
                }


            })
            .catch((error: any) => {
                reject(error);
            });
    });
}

deleteDocument(collectionName: string, docID: string): Promise<any> {
  return new Promise((resolve, reject) => {
      this.db
          .collection(collectionName)
          .doc(docID)
          .delete()
          .then((obj: any) => {
              resolve(obj);
          })
          .catch((error: any) => {
              reject(error);
          });
  });
}

addDocument(collectionName: string, dataObj: any): Promise<any> {
  return new Promise((resolve, reject) => {
      this.db.collection(collectionName).add(dataObj)
          .then((obj: any) => {
              resolve(obj);
          })
          .catch((error: any) => {
              reject(error);
          });
  });
}

updateDocument(collectionName: string, docID: string, dataObj: any): Promise<any> {
  return new Promise((resolve, reject) => {
      this.db
          .collection(collectionName)
          .doc(docID)
          .update(dataObj)
          .then((obj: any) => {
              resolve(obj);
          })
          .catch((error: any) => {
              reject(error);
          });
  });
}

Add the methods used by the view to add, edit,list and delete items:

  loadData(){
    this.getAllDocuments("messages").then((e)=>{
      this.messages = e;
  });
  }

addMessage(){
    if(!this.isEditing){
    this.addDocument("messages", this.model).then(()=>{
      this.loadData();//refresh view
    });
  }else{
    this.updateDocument("messages", this.model.$key, this.model).then(()=>{
      this.loadData();//refresh view
    });
  }
  this.isEditing = false;
  //clear form
  this.model.title = '';
  this.model.text = '';
}

updateMessage(obj){
  this.model = obj;
  this.isEditing = true;
}

deleteMessage(key){
  this.deleteDocument("messages", key).then(()=>{
    this.loadData();//refresh view
    this.isEditing = false;
  });
}

Now you can run:

ionic serve

The result should be something like this:

You can download the full source code from here:
https://github.com/jomendez/ionic-firestore-crud-example

Happy coding!!