Category: Angular2

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 lest 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!!

Ionic 2 google signin Error 10 with firebase

The mysterious Error 10

I hope this article helps to clarify and find a solution quickly to the Error 10 using ionic 2 framewrok with firebase sign in and cordova-plugin-googleplus. I was developing an Ionic 2 application “quiz dev” to create a playful platform for developers to practice and improve their skill through quizzes, based on the spaced repetition approach. I wanted to provide the user the ability to sing in into the application using their google account.

error 10

The issue

The point is, that I’ve spend 2 or 3 days trying to figure out the error 10 I was receiving once I deployed to the Android Play Store. I followed the official documentation of Ionic https://ionicframework.com/docs/native/google-plus/

I installed the cordova-plugin-googleplus and implemented the plugin (I going to skip high level details, for more information refer to the documentation provided here)
 

  this.googlePlus.login({
        'webClientId':'#############-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
        'offline': true
      })
          .then(res => {
             //logged in
              ...
          })
          .catch(err => {
              alert("There is an error " + JSON.stringify(err));
          });

 

After that, I signed my debug.apk following the steps here, this is the google official documentation, then I get the SHA-1 fingerprint certificate that is going to be needed to setup the firebase project, you can do it via cmd following these steps. The result is going to be something like this:
sha-1 fingerprint certificate

I had set up a Firebase project, following the steps here https://chriztalk.com/ionic-2-firebase-google-authentication/

The headache

At this point installing the application in my device in release or debug mode, everything was working properly. Then I decided to deploy it to the google android app store. When installing the app from the android app store I wasn’t unable to login with my google accounts, the previous code to handle the google sign in was entering in the catch section and showing an alert with error 10
 

 
          .catch(err => {
              alert("There is an error " + JSON.stringify(err));
          });

The solution

After spending hours and hours trying to figure out what the issue was, I realize that there is an option when you are setting up your application in the google app store that ask you if you want to sign your apk in the store. After you say yes it shows you a message like this:
google app store apk sign
 

the real solution is to go to Release Management/App signing section and get the SHA-1 fingerprint certificate and include it in your Firebase project
 
app signing google android app store

Go to your Firebase project configuration and add you SHA-1 fingerprint and it will do it
 
firebase add sha-1 fingerprint

Final thought

I really hoe this save you a lot of time of banging your head against the wall.

Here is a demo of the app, you can from android to ios here. The is the application in the android app store in case you are interested https://play.google.com/store/apps/details?id=com.evolutionsys.quiz&hl=en

Angular 2 seed for Visual Studio 2015

Angular 2 seed for Visual Studio 2015

This Angular 2 seed for Visual Studio 2015 targets Angular version 2.1.0 released on Oct 12, 2016. This project is based on official Angular2 Seed project. It relies on TypeScript and SystemJS.

angular 2 seed

Instructions:

-1 Clone or fork the repocitory.
https://github.com/jomendez/AngularJs-2-Visual-Studio-2015
-2 Make sure you have node installed, this code require node v5.x.x or higher and npm v3.x.x or higher, to check what version you are using run node -v and npm -v, in your cmd console.
-3 Open a cmd console, and go to your project root file location and run npm install to install dependencies

npm behind a corporate proxy

If you are trying to setup the seed behind a proxy, you migth encounter issues of connection refuced, etc. You can use the following command:
With password:

npm config set proxy=http://<username>:<pass>@proxyhost:<port>
npm config set https-proxy=http://<uname>:<pass>@proxyhost:<port>

or without password:

npm config set proxy=http://proxyhost:<port>
npm config set https-proxy=http://proxyhost:<port>

 

Fixing errors when using resharper

If you don’t have installed resharper in your computer please ignore this section, if you have it intalling, resharper migth cause cause some sintax error validation.

Error:
“Typescript Feature 1.5. Current language level is 1.4”.

Solution:
Resharper setting. From the menu bar in VS2015 -> Resharper -> Options -> Code Editing -> TypeScript -> Inspections -> Typescript language level, change to 1.5

Error:
Symbol ‘component can not be properly resolved, probably its located in an inaccessible module’

Solution:
You can disabled resharper’s typescript inspection for now.
Resharper > Options > Code Inspection > Settings
Find ‘File masks’ (bottom right) and add *.ts

 

Browser support

The Angular 2 seed runs on all major browsers including Internet Explorer 11+, Edge, Firefox, Chrome, Opera and Safari.

License

The Angular 2 seed is released under the MIT license.