Showing posts with label cloud. Show all posts
Showing posts with label cloud. Show all posts

Saturday, October 8, 2016

Getting started with AngularFire 2

The blog describes using AngularFire2, Angular 2 and TypeScript API for Firebase. It is a beginner guide with a sample for retrieval and update to Firebase database.
Blogger: V. Keerti Kotaru . Author of Angular Material book . Twitter @KeertiKotaru . linkedin.com/in/keertikotaru

Firebase started as a cloud database that can store and retrieve JSON objects. It provided an effective database solution for mobile apps and other applications. Today if you look at the newer version of Firebase, database is only a part of it. It has great analytics features, push notifications to mobile & Chrome and Firebase Cloud Messaging (FCM).

Realtime Database

Firebase database has a unique feature to synchronize database and clients systems automatically. In case of Web UI, it uses a Web Socket connection to push changes to the client. As and when there is a change to the JSON data on the cloud DB, it is pushed to all connected clients.

Sample - Bus Schedule Management: For the blog, I built a couple of pages that deal with bus schedule management. A page to list buses and schedule. And another page to update if there is delay in the arrival time for a bus. 

Consider figure 1. The window on the left shows list of buses to the passengers. The window on the right could be used by admins to update if there is a delay in arrival. The sample is using AngularFire2 (Firebase API for Angular2 & Typescript) to connect with the Firebase database. As and when there is a change to ETA (Expected Time of Arrival), it's instantly synchronized with all clients.

Checkout complete code sample here..


Figure 1: Real time updates
Figure 2: A Sample Firebase App
Left Nav with feature List.

This blog uses AngularFire 2 & Typescript for the Firebase API. Firebase integrates with multiple platforms including Android, iOS and Web. While the Web JavaScript API is for plain JS that could be use in any HTML/JS app, the AngularFire is AngularJS specific API.

AngularFire 2 is in beta at the time of writing this blog. It uses Angular 2. And code in this blog uses TypeScript along with Angular.

Getting Started - Create an app on Firebase console

  • Log into firebase at firebase.google.com. Sign-up if you don't have an account already.
  • Once logged-in,  click on "Go to console".
  • It lists an existing Firebase apps. If it's a new account create an app. 
  • Click on the app to see various features provided by Firebase.

Create Angular 2 Project

Angular CLI is preferred tool for scaffolding an Angular 2 application. Create a new Angular2 app using the following command. It will also install the dependencies.


ng new angular-fire-2-sample

Note: If you do not have Angular CLI already installed, follow the link to get instructions on installing the tool. 


Add angularfire2 and firebase package references


To use AngularFire2 and firebase API in the project, install the package using the following command.


npm install firebase angularfire2 --save
(--save will update to package.json for future installation of required dependencies)


Add AngularFire2 app to Angular Module

In the scaffolded project the main module is in the file  src/app/app.module.ts
Edit this file to import AngularFireModule from angulafire2
import {AngularFireModule} from 'angularfire2';


Create configuration object. 

// API documentation suggests to export the configuration
export const config = { 
 apiKey: "[API Key]", 
 authDomain: "gdg-bustracker.firebaseapp.com", 
 databaseURL: "https://gdg-bustracker.firebaseio.com", 
 storageBucket: "" 
};

Follow below steps to create the configuration object readymade.
  1. Click on settings icon next to the app in Firebase Console.
  2. Click on "Add Firebase to you Web App" link. It presents the configuration object.
  3. Copy the configuration to the AngularFire app.
Figure 3: Two easy steps to get to Firebase configuration to be added to the Web App
Add reference to the module in the module imports. Consider following code,
@NgModule({ 
 declarations: [ AppComponent ], 
 imports: [ 
       BrowserModule, 
       FormsModule, 
       HttpModule, 
       AngularFireModule.initializeApp(config) // initializes and import Firebase module     ], 
 providers: [], 
 bootstrap: [AppComponent] 
})

Note: There is an open bug, that could result in build errors with firebase package. Add the following line in src/main.ts to circument the problem temporarily.

import * as firebase from 'firebase';

Now Firebase API is ready to use.

Create a service to integrate with Firebase

It is a good idea to keep the bus data access in a separate service. It could be injected in components while dealing with bus data.

Create the service using Angular CLI with the following command.

ng g service bus-data-access

The generated class is named BusDataAccessService. Provide the service in the main module (app.module.ts). Consider following code snippet,
// import the service module 
import { BusDataAccessService } from './shared/bus-data-access.service'; 

// add it to providers list in the module. Note that the @NgModule decorator is stripped off additional details for readability. Look at the file in github for complete code. @NgModule({ 
 declarations: [ ], 
 imports: [ AngularFireModule.initializeApp(config) ], 
 providers: [ BusDataAccessService], // *** the service is provided here (to the module)
 bootstrap: [AppComponent] }) 
export class AppModule { }

Import the following in the newly created bus-data-access.service.ts file,
import { AngularFire, FirebaseListObservable } from 'angularfire2';
  • AngularFire - provides API for various firebase services. In the BusDataAccessService, we use it to interact with database.
  • FirebaseListObservable - An RxJS observable. The BusDataAccessService returns the observable (list of buses) which could used in the template. Please note, the bindings in the template are asynchronous with observables.

Retrieve the bus list

Consider following code in the BusDataAccessService for retrieving bus list.
// Class property for bus list 
 buses: FirebaseListObservable; 

 // inject AngularFire service 
 constructor(firebase: AngularFire) { 
   // get bus list from schedule node on the Firebase DB. 
   this.buses = firebase.database.list("/schedule"); 
}

We are retrieving bus list from a node named schedule in the JSON stored on Firebase DB. Here is the structure of bus object I have. The FirebaseListObservable object yields a list of these objects.
"A2F001": { 
   "from": "Hyderabad", 
   "to": "Bengaluru", 
   "expectedTimeOfArrival": "10/02/2016 10:00", 
   "scheduledTimeOfArrival": "10/02/2016 10:00", 
   "delay": 0, 
   "delayReason": "N/A" 
 }

A function getBusList on BusDataAccessService returns the observable.
getBusList(){ 
  return this.buses; 
}


Update changes to Bus Schedule

We use another function in BusDataAccessService for updates to the bus schedule. Consider following code.
  saveBusData(id, expectedTimeOfArrival, delay, delayReason){
    this.buses.update(id, {
      expectedTimeOfArrival:expectedTimeOfArrival,
      delay:delay,
      delayReason: delayReason
    })
  }

In the given application I anticipate changes to three properties, expected time of arrival, delay in minutes and delay reason. The save function expects these as parameters.

We also need to know which bus schedule is being updated. The first parameter, id should have the unique identifier for the bus JSON object.

The update API (in AngularFire) expects field being updated as a key and the new value as the value. We are using ES2015 syntaxes. When the key and value variable names are the same (on the JSON object), we don't have to write them twice. Will cleanup this payload as the following.


  saveBusData(id, expectedTimeOfArrival, delay, delayReason){
    this.buses.update(id, {
      expectedTimeOfArrival,
      delay,
      delayReason
    })
  }


Integrate the BusDataAccessService with the components

Component shows the bus data on the screen. Component calls the above written getBusList() of BusDataAccessService.

As a first step, import the service in bus-list.component.ts
import { BusDataAccessService } from '../shared/bus-data-access.service';

In the constructor inject the service and call getBusList function. The returned data is assigned to a field buses on the class.
  constructor(dataService: BusDataAccessService){
    this.buses = dataService.getBusList();
  }

In the template iterate through buses asynchronously. Refer to async filter on the *ngFor. Note that the field buses is an observer. Unlike an array, whole list is not available in an observer upfront. Each record is asynchronously obtained.

Consider following template snippet from bus-list.component.html 
<div *ngFor="let item of schedule | async">
        <h3 class="panel-title">{{item.from}} to {{item.to}}</h3>
        <!-- other similar bindings go here. Refer to file in github for complete template. -->
</div>


Make updates to bus data

 In the sample repo, another component admin has controls to update delay information. Refer to figure 1, which let's user add delay in minutes and reason for the delay. The admin component has similar template to that of bus list, with additional controls to increment/decrement minutes and a text area to input reason for the delay.

As user updates delay information and clicks on the save button, following handler is called in the component class. It in-turn calls the saveBusData function in BusDataAccessService, which is using the Firebase API to update the database.
   save(item){
    this.busDataAccess.saveBusData(item.$key,
      item.expectedTimeOfArrival,
      item.delay,
      item.delayReason
    );
   }

Template for the button in admin component
<button class="btn btn-info" (click)="save(item)">Save</button>

References and further reading

AngularFire 2 Github
Follow this link for complete code sample
Firebase Docs

Monday, November 30, 2015

Firebase - Two Salient Features.

Three way data binding with AngularFire:

Imagine user keys in lots of data into a form and had to navigate away from the page. Often I saw apps presenting a dialog box that says data is going to be lost. I don't think it's a good solution. How about allowing user start from where he/she left. Here is a Firebase feature to address the same,


Maintain state as you move away from the form:

Among many things AngularJS provides, two way data binding is salient. Firebase takes it further, add another dimension - data store. Three way data binding synchronizes, view (Html template), model (Scope) and Firebase data store.

Consider following code snippet

// Initialize Firebase object
// say user variable has user name of the logged in user.

     var firebaseObj = $firebaseObject(new Firebase("< Firebase Data Source Url >").child(user));
     // three way data bind email message field on scope to firebase object created above.
     firebaseObj.$bindTo($scope, "emailMessage");


Any changes to $scope.emailMessage are bound all the way to data source on Firebase. User can any time navigate away and yet data is not lost. As and when user comes back to this page, can start where he/she left off.


In the video, on the left is the form field and on the right is the Firebase data source. You can see it's updated as and when more characters are typed into the text area.

Sync as you go online: 

Firebase makes it that much more easier to continue to work as you get disconnected. In fact no additional code required. API automatically maintains data in disconnected state. It will sync as and when user goes online.


Knowing connection state:

Use /.info/connected on the data source's URL to know current connection status.

$scope.connectionStatus = $firebaseObject(new Firebase("https://Your Firebase App/.info/connected"));

Bind connection status to a green/red icon in the template. 

 <img ng-show="connectionStatus.$value" src="images/green.png" style="max-height:24px" />
 <img ng-show="!connectionStatus.$value" src="images/red.png" style="max-height:24px" />


Track connection status on server-side

JavaScript API onDisconnect will attach a server side event. You may set a value when disconnection occurs,

// The variable "user" holds user name of the logged in user
// If Kotaru is the user name, JSON will be {Kotaru:{conectionStatus:"disconnected"}}


firebaseReference.child(user).child("connectionStatus").onDisconnect().set("disconnected");

// You can override this object when user comes online

JavaScript API to get Offline or Online:

Finally you may chose to go offline or online with functions Firebase.goOffline() and Firebase.goOnline() . These are as good as disconnecting and connecting the application's connection with Firebase. You might allow user to perform multiple offline changes to dataset and at some point get online to sync. 

Wednesday, October 28, 2015

Highlights: Firebase, Parse & Azure Mobile Services

Cloud back-end services are revolutionary in quick application development. It takes care of routine code. Many times we write services that act as pass through between UI and data store. Consider two tier architecture with cloud back-end services; Your HTML page or mobile app is directly interacting with cloud back-end. More often than not you don't need to develop middle tier. The back end service acts as one.

In this blog I'm attempting write about Firebase, Parse and Azure Mobile Services.

  • It's quite easy to integrate C.R.U.D operations in your application using any of these services. 
  • They are "cloud" based, so **no** data center or server setup required. They are all ready to hit the ground running.
  • This approach is quite useful for mobile app developers who don't have to setup servers around the world to support their user base. Lot of logic can be written client side and these services provide effective data store and related services.
  • All of them have user services and authentication related features.

Which additional features each of these back-end services provide? Let's find out.

Firebase Highlights


  • Late last year (2014) Google acquired Firebase, a promising back-end service. 
  • Firebase data has no schema. Data is represented as JSON objects. Each node or element in the JSON object has it's own URL. So if you need to reference a child node in your code, can do so by directly referencing it's URL.
  • Firebase has API for Android, iOS, Web (JavaScript) and REST API. These are many ways in which your code can interact with Firebase.
  • Firebase clients are always synchronized. It's a huge. You don't have to write code push message or data changes to the client (or poll from the client). As and when data is modified in the back-end, changes are pushed to all of it's clients.
  • It fits naturally with AngularJS. If you are an ng developer you are in luck :)

Here is one of my earlier blogs on Firebase


Firebase

Parse Highlights


  • Parse was acquired by Facebook in 2013. They provide back-end services for mobile and web applications.
  • Cloud core provides data storage. It too is schema less. But Parse makes it explicit on how to deal with relational data. Refer to this link.
  • Parse Cloud Functions allow adding additional logic on Parse server side. You could add additional validations, send push notifications etc (on server side).
  • Parse push is a very useful feature. It allows sending push notifications to multiple mobile platforms Android and iOS. You can preview notification, schedule it personalized for the user. For example a notification scheduled for 11 AM in the morning in U.S. wouldn't wake up customer in India middle of the night. Rather personalizes to send it at 11 AM India time.
  • JavaScript perspective Parse fits naturally with backbone style of coding. It supports huge list of technologies and platforms. Refer to the image for list.
  • Finally Parse features Core and Push could be used independently. You don't need to be using Core to use Push and vice versa.
A link to my earlier blog on Parse

Azure Mobile Services Highlights

It's little tricky to include Azure Mobile Services in this list. It's one of many features and services Microsoft Azure provides. I believe it fits in the category of Parse and Firebase as it provides lot of out of box features for faster development and integration of back-end services.

  • Schema: Azure Mobile Services by default uses MS SQL Server for data storage. As it's possibly using code first, you don't have to define columns (schema). They are effectively created on the fly. 
  • Unlike other back-end services, with Azure Mobile Services you can chose data storage from SQL Server, Mongo DB and Azure Storage
  • You have a choice for backend technology as well between .net and JavaScript (NodeJS)
  • Similar to Parse Cloud Functions Azure Mobile Services allow adding additional code on server side. In Azure Management Portal, select your Azure Mobile Services, go to data tab, select the table and select Script tab. Use drop down to modify script for add or update or retrieve or delete operations.
  • Azure Mobile Services provide Push Notifications across mobile platforms Windows, Android and iOS. It integrates with MPNS (Windows),  APN (iOS) and GCM (Android) services for push notifications.
  • Azure Mobile Services have APIs for following platforms,


Here are my earlier blogs on Azure Mobile Services, Mongo DB with Azure Mobile Service, Push Notifications for Phone App using Azure Mobile Services and Windows Azure Mobile Services for Connected Apps

In conclusion one of the biggest advantages of cloud back-end services is time to develop. They reduce lot of routine code and provides features out of box. 

Sunday, September 20, 2015

Azure Mobile Service as your App's backend

In continuation to the two previous blogs (Parse and Firebase), in this one describing Azure Mobile Services. It's an another option for cloud based back end that's quick to get started. Microsoft Azure is a sophisticated cloud service provider with great pricing options.

In this blog, focus is on server side code. I'm picking JavaScript back end (NodeJS) for Azure Mobile Service, which will be configured to use MongoDB for data storage.

If you are looking for JavaScript code consuming the Mobile Service use my earlier blog. It's using SQL Azure and a table for storage.

Let's get started. Log into Microsoft Azure Management portal.

Using MongoLab for our Mobile Service

Let's use Mongo Lab for the database integrating with Mobile Service. It provides MongoDb as a service on the cloud. Checkout more here.
This is also available on Azure Market Place, which we will use in this sample.
  1. Click New, Select Market Place. 
  2. Find and select MongoLab
  3. Click next and select your plan. I'm choosing Sandbox, which is free for the purposes of this blog.
  4. Click next, review and complete the purchase.

Once done select Mongo service in the Portal. Click Connection Info. Copy the connection string.


Working with Azure Mobile Service

Select the Mobile Service we wanted to work with. Make sure it's JavaScript back end. Dot net back end services have slightly different options.

Setup Source Control and clone to your machine.

Setup Source Control by clicking Setup Source Control in dashboard tab. This is required to be able to add MongoDb NPM Package to the Mobile Service back end.

Next navigate to Configure tab, copy git Url.

(Note: You always have a git URL at this place. I had to find it hard way, unless Setup Source Control is done, git URL doesn't work. I was hoping it will work with Microsoft/Azure credentials, but it has it's own user id and password)
  1. In any folder on your machine, use git clone << git URL >>
  2. Use npm install mongodb
  3. Commit and push your changes.
    • git add --all
    • git commit -m "Added MongoDB Package"
    • git push
Now the Mobile Service is ready for MongoDB Code.

Modify the mobile service to integrate MongoDB (instead of tables)

In the Mobile Service, select Data tab and resource you want to work with. In this example resource is named Book.


Next select Script tab. Here we can select Insert, Update, Read and Delete from the drop down. The script for each operation has one line by default request.execute(), which performs respective action to the SQL table. We can add additional server side validations if we wish to.

For using Mongo DB we are going to modify the script to update Mongo DB instead of SQL Table. Below are basic scripts to do so. You might improvise on these to make it more sophisticated.

Note: if you leave request.execute() it will also perform operation to the table. One interesting idea would be to go to Mongo for specific kind of data and use table for the rest.

C . R . U . D

In the data tab and selected resource (table) use drop down to switch between C.R.U.D (Create/Insert, Retrieve/Read, Update and Delete) and write code to read/insert/update/delete from MongoDB.

client.connect takes connection string, which was copied from MongoLab Market Place service earlier in the blog.



Note- Mobile service uses Patch instead of put for update

































In conclusion Azure Mobile Services are flexible to use with multiple data storage options other than the default tables and yet it's quick to get started with many out-of-box features. There are many other Mobile Services' features like Push notifications, Scheduled Jobs etc. I hope to hack more of it soon.

Happy Coding.

Thursday, September 10, 2015

Parse as your app's backend

Parse is a cloud based backend service. For an application either a mobile app or a web app, Parse provides storage, SDK for easy integration and cloud services for additional processing including push notification support, analytics etc.

Parse provides APIs for variety of technologies. This blog is focusing on JavaScript. The framework is inspired by backbone and it's style of coding in JavaScript. Lot of articles use Handlebars and other templates in their examples. For simplicity, I'm using JQuery in this blog.

Get Started

  1. Once you register and login at Parse.com, create an app and launch quick start guide for it.
  2. Choose Data - Web - and New Project
  3. Here you can chose to download a blank HTML/JavaScript project or explore APIs to be added in an existing project.

Core

Parse Core provides data storage, retrieval and Data Browser. The Data Browser allows you to create one or more classes (which can be visualized as a table - refer to the screenshot). Here you can add/delete and modify data. It's the same data your app is integrating with, so changes are reflected in your app automatically (as you refresh screens).

Click on Add Class - provide name. It creates a table with default columns like objectId, CreatedAt, updatedAt etc. Click +cols to start adding custom columns.


Now, get started with code-

// Get started with initialize function
Parse.initialize("[application_id]", "[JavaScript Key]");

You get these keys as soon as you create the app. You could go to Key's screen to view and copy all available keys. If you chose to download the blank template you may use boilerplate code.

Create an object of class created in Data Browser. I'm referring to a class named book in my example.

var Book = Parse.Object.extend("book");

// Now create an object of book.
var book = new Book();

C.R.U.D

Following code demonstrates Create, Retrieval, Update and Delete of books data
// Create new records
// use set
book.set("aKey", "aValue");


Key here is same as column name in Data Browser

// Or set all column values at one-go.
book.set({aKey: 'aValue', secondKey: 'secondValue'});

//save creates the record for the table/class

// you may pass above object instead of null/first param. Then set is not required
book.save(null, {success: function(response){
   // On successful save response has all saved records.
}, error: function(error){
  // error information if occurred is in error object.
}
});


// ----------------------------------------------------------------- // Retrieval
// To Parse.Query function pass the class 
// Book below is not new'ed. It's returned value of Parse.Object.extend(). Refer to code above.
var query = new Parse.Query(Book);

// You may filter with queries like below. This looks for key with a value specified
query.equalTo("key", "value");

//or directly calling find() returns all records
query.find({
success: function(results){
for (i in results){
var data = results[i];

    // addBookRow() updates DOM with new row.
addBookRow(data.get("title"),
data.get("author"),
data.get("publisher"));
}
},
error: function(error){
$(".error").hide();
console.error(error);
}

// ----------------------------------------------------------------- // Update by getting an instance of book class for an existing record.
// I used find() for it.
query.find({
   success: function(result){
        // Get first row from results
var row = result[0];

        // update the first "title" column with new value
        row.set("title", "new value");
        row.save(null, { success: function(){}, error: function(){}});

   }
});

// -----------------------------------------------------------------
// Delete by getting an instance of book class for an existing record
// Used query.find to get it
query.find({
   success: function(result){
        // Get first row from results
var row = result[0];

        // Delete with destroy function.
        row.destory({ success: function(){}, error: function(){}});

   }
});

Refer to complete sample here

This is a introductory blog on Parse, planning to followup with concepts of
  • More queries and explore more of JavaScript parse library
  • Cloud code - additional hooks and validations on cloud. It's server side logic. Used instead of adding complex logic with-in a browser or a mobile app.
  • Parse Push - Easy integration of Push for various mobile platforms. Currently it's only for mobile devices.
Have fun Parsing!

Sunday, September 6, 2015

Firebase as your app's backend


Firebase is a cloud based back-end as a service provider. It can be used as a very effective No SQL data-store. Your application can store JSON objects. Integration is made easy with variety of libraries provided by Firebase. For this blog I'm focusing on Web/JavaScript library.

As a developer it's quick to get started. No overhead of installation and setup. It's a cloud service, so don't have worry about setting-up servers. Firebase tools on your machine are provided as an NPM package. Install with following command, globally on your machine.

npm install firebase-tools -g

This makes it a good choice for independent mobile/web app developers. Signup and login to Firebase.
Create an app. Remeber your app has a URL. JSON Key/Value pairs are shown at that URL. You might chose to manually add/remove/modify data as well.

Synchronized:

As and when data is updated in the backend, JavaScript events are raised and the callbacks provided are invoked with updated data. Hence your app is in near synchronous state all the time. With this approach we write less code, retrieving data is made simpler. Down below I've mentioned couple of data retrieval options. Checkout more here.

Consider Two Tier Architecture

With JavaScript and browsers being more and more powerful, you don't have to look at mandatory middle tier. Firebase can act as your middle tier and data store. Security, validation and authentication features of Firebase do allow this kind of architecture. 

Get Started

by referencing Firebase library in your Web Page. You could use CDN location. Or by downloading Firebase bower or npm package. I chose bower (package manager).

bower install firebase

And reference of firebase.js in bower_components. There after

//create an object of Firebase
var ref = new Firebase('URL of your firebase app');

Save Data to Firebase:

// to set a primitive data value
ref.set('sample value')
ref.set(100);

// you may set a JSON object instead
ref.set({
field1: 1,
field2: {
  child1: 'value'
}});

//If you are storing a new object every time, use push (array) instead of set.
ref.push({
field1: 1,
field2: {
  child1: 'value'
}});

Retrieve data from Firebase:

As mentioned earlier, Firebase keeps data synchronized. Data is pushed to the browser as changes happen. JavaScript code need to have callback functions defined to update view as data is retrieved automatically.

//Look for changes to the data
ref.on('value', function(snapshot){
    console.log(snapshot.val());
});

// data added as a child node.
ref.on('child_added', function(snapshot){
    console.log(snapshot.val());
})


All data elements in Firebase are represented by URL. You can traverse through the nodes in the URL itself. For example, to reach child1 in above example, you could provide URL "http://yourapp.firebase.io/field2/child1" to the Firebase function.

or you could use ref.child('field1/child1')


Running your application:

You may use any Web-Server to serve HTML files on your machine. Serve is a good choice.

npm install serve -g

Run serve from at the root folder of your application.
Firebase also provides hosting service. Run

firebase init
(Link application to Firebase app in this step.)

firebase deploy
(Deploys to Firebase cloud service)

You can serve HTML files on the cloud now. URL is on App Card It will be your appname.firebasepp.com

This is an introductory blog. Do checkout Security, Authentication, OAuth and Offline features of Firebase.


Also, I've basic Firebase examples on my Github. Use this link to explore.