Sunday, October 29, 2017

Firebase Real Time Database for Web App

1) Create a Firebase project

- Create a firebase Project at https://console.firebase.google.com
- Go to Project Overview -> Click "Add firebase to your webapp"
- It will open a popup and you will find apikeys and endpoints as per your project settings.
- You will use this data in your frontend html file that will connect to firebase.
- Go to Database -> Rules and update the content as following

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

This will allow anyone to read and write to the database. Its only for testing purpose. In actual production app you can see more complicated rules. You must not do this for your production app.

2) Checkout the following frontend demo app from github.

https://github.com/fullstacktechnos/firebase-frontend

- I am using node.js as local server to serve the page. If you want to use node.js then please check the following article:

http://www.fullstacktechnos.com/2017/10/serving-static-file-using-nodejs-and.html

- I have a single page called index.html and a config file called firebaseconf.js inside public. Config file has all dummy data. You have to replace with your actual project configs.
- Open the firebaseconf.js inside public folder.
- Add the firebase initialization code.

  // Initialize Firebase
  var config = {
    apiKey: "bjfuawfbajbawfbawawfbfawbbawflf",
    authDomain: "testproject.firebaseapp.com",
    databaseURL: "https://testproject.firebaseio.com",
    projectId: "testproject",
    storageBucket: "testproject.appspot.com",
    messagingSenderId: "123456789123"
  };
  firebase.initializeApp(config);

* I have added all dummy data. Please use the actual data in your project.  

- Open the index.html and check the following code.

Send data to Firebase

                             //Send data to DB
            $("#sendmsg").click(function() {
                var content = $("#content").val();
                if (!content) {
                    return console.log('No content');
                }
                $("li").remove();
                var ref = firebase.database().ref('messages');
                var data = {
                    type: 'Generic',
                    description: content
                }
                ref.push(data);
            });


- In the above piece of code I am getting the message text from the html element (with id 'content') and sending it to the firebase when user clicks on the button (with id 'sendmsg'). Check the elements in the index.html.
- firebase.database().ref('messages') will get the database reference. Create the payload and send it to the firebase realtime db with ref.push(payload).

- Once message sent successfully go to firebase console. https://console.firebase.google.com
- Inside your project, go to Database.
- Check the messages.
- You will find the new message inside uid with your given content in description.


Getting data from Firebase

- You need to listen to the database event in your frontend webapp to get db updates.
- Check the following code.

                            //Read Data
            var ref = firebase.database().ref('messages');
            ref.on('value',function(result) {
                var messages = result.val();
                if (messages) {
                    $("li").remove();
                    keys = Object.keys(messages)
                    keys.forEach(function(key) {
                    console.log('Type :' + messages[key].type + ' :: Content :' +  messages[key].description);
                    $("#messagelist").append('<li class="singlemsg">' + messages[key].description + '</li>');
                    });
                }
            }, 
            function(error) {
                console.log(error);
            });


* If you have not checked out the code from git then please don't worry about dom manipulation code written above. Just ignore them.


- Get the reference of the database and call ref.on. It will be invoked whenever there is a db insert or update on messages. Get the result and show to the user.
- You can notice as soon as you send the message to firebase it will be displayed in the page.


Note :

For more info please visit firebase official documentation link given below.
https://firebase.google.com/docs/database/web/start

To know more about firebase and cloud functions please find the below articles:
1) http://www.fullstacktechnos.com/2017/10/firebase-authentication-service-for-web.html
2) http://www.fullstacktechnos.com/2017/10/why-we-need-firebase-cloud-functions.html
3) http://www.fullstacktechnos.com/2017/10/introduction-to-cloud-functions-for.html

Saturday, October 21, 2017

Firebase authentication service for web app

To understand firebase authentication service, lets create a simple frontend web app which will talk to firebase.

1) Create Firebase project

- Create a firebase Project at https://console.firebase.google.com.
- Go to Project Overview -> Click "Add firebase to your webapp"
- It will open a popup and you will find apikeys and endpoints as per your project settings.
- You will use this data in your frontend html file that will connect to firebase.

2) Enable Sign-In Method from Authentication

- You are inside your project in https://console.firebase.google.com.
- Go to Authentication tab from left side menu.
- Click on the SignIn Method. You will be seeing all the supported methods like Email/Password, Phone, Google, Facebook, Twitter etc.
- Enable Email/Password and Google.

3) Create frontend webapp

- You can download the project from the git from the below location or you can use your own.

https://github.com/fullstacktechnos/firebase-frontend


- I am using node.js as local server to serve the page. If you want to use node.js then please check the following article:


http://www.fullstacktechnos.com/2017/10/serving-static-file-using-nodejs-and.html


- I have a single page called index.html and a config file called firebaseconf.js inside public. Config file has all dummy data. You have to replace with your actual project configs. I am using jquery to access dom element.

- Open the firebaseconf.js inside public folder.
- Add the firebase initialization code.


  // Initialize Firebase
  var config = {
    apiKey: "bjfuawfbajbawfbawawfbfawbbawflf",
    authDomain: "testproject.firebaseapp.com",
    databaseURL: "https://testproject.firebaseio.com",
    projectId: "testproject",
    storageBucket: "testproject.appspot.com",
    messagingSenderId: "123456789123"
  };
  firebase.initializeApp(config);


Go to the index.html. I have already created the elements and added event listener to call to firebase. However if you want to create your own please follow the steps below.

- Create email and password field and 4 buttons. Signin, Register, Signin With Google, Signout
- Add event listener for all the buttons.
- Call the firebase authentication service for respective actions.
- Google service will handle all the error conditions. You don't need to worry about it. Check the console after each event.


User Registration:

- At the time of user registration, get the email and password and call the firebase auth service createUserWithEmailAndPassword. 
- If the email is already in use, try logging in using google signin. Google signin code is mentioned below in the article.
- Once the user is created successfully you can find it in firebase console. 
- Go to your project inside https://console.firebase.google.com
- Go to "Authentication" -> "Users"
- You can find the newly created user details.
- You can also add/delete user account from the firebase console.



                              $("#register").click(function(e) {
                var email = $("#email").val();
                var password = $("#password").val();
                if (!email || !password) {
                    return console.log('email and password is required');
                }
                firebase.auth().createUserWithEmailAndPassword(email, password)
                .then(function(result) {
                    console.log(result);
                })
                .catch(function(error){
                    // If user is already registered with the same email
                    // then try to login using google signin
                    if (error.code === 'auth/email-already-in-use') {
                        var credential = firebase.auth.EmailAuthProvider.credential(email, password);
                        var provider = new firebase.auth.GoogleAuthProvider();
                        firebase.auth().signInWithPopup(provider)
                        .then(function(result) {
                            console.log(result); 
                        })
                        .catch(function(error1) {
                            console.log('Google sign in error', error1);
                        });
                    }
                })
            });



User Signin :

- At the time of user login, get the email and password and call the firebase auth service signInWithEmailAndPassword. 
- Test with email that is not present in firebase. 


                          $("#signin").click(function(e) {
                var email = $("#email").val();
                var password = $("#password").val();
                if (!email || !password) {
                    return console.log('email and password is required');
                }
                firebase.auth().signInWithEmailAndPassword(email, password)
                .then(function(result) {
                    console.log(result);
                })
                .catch(function(error) {
                    console.log('signIn error', error);
                })
            });


Google Signin :

- It will work if the page is served from a server.
- If you directly open the index.html or your static file in browser it may not work. So better you use any static server to host the page. I am using node.js for it.
- Get the auth provider and use it to call the service. 
- I am using popup window to enter the google credentials so calling signInWithPopup(). 
- You can even use signInWithRedirect()


                            $("#gsignin").click(function(){
                $("#message").text("");
                // Sign in with Google
                var provider = new firebase.auth.GoogleAuthProvider();
                provider.addScope('profile');
                provider.addScope('email');
                return firebase.auth().signInWithPopup(provider)
                    .then(function(result) {
                        console.log(result); 
                    })
                    .catch(function(error) {
                        console.log('Google sign in error', error);
                    });
            });


User Signout :

Call the auth signOut() function.

                $("#signout").click(function() {
                firebase.auth().signOut();
            });


Listening to Auth State :

- Place the following code once the document is loaded. Its not part of any button event listener.
- It will write the user object data to console for debugging purpose every time there is a change in authentication state like user registration, login, signout etc.

           firebase.auth().onAuthStateChanged(function(user) {
                console.log('user', user);
            });



Note :

For more info please visit firebase official documentation link given below.

https://firebase.google.com/docs/auth/web/start


To know more about firebase and cloud functions please find the below articles:

1) http://www.fullstacktechnos.com/2017/10/why-we-need-firebase-cloud-functions.html

2) http://www.fullstacktechnos.com/2017/10/introduction-to-cloud-functions-for.html

Serving static file using node.js and express

Setup:

Make sure you have NODE and NPM installed in your local box.

Rajas-MBP: raja$ node -v
v6.11.3
Rajas-MBP: raja$ npm -v
3.10.10

Step-1

Initialize Node Project and Install Express.js

Rajas-MBP:Youtube raja$ mkdir node-static-page
Rajas-MBP:Youtube raja$ cd node-static-page/
Rajas-MBP:node-static-page raja$ npm init

* Give the project related information or you can choose default by pressing enter.

Rajas-MBP:node-static-page raja$ ls
package.json

Rajas-MBP:node-static-page raja$ cat package.json 
{
  "name": "node-static-page",
  "version": "1.0.0",
  "description": "Node Server to Serve Static Page",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "raja",
  "license": "ISC"
}

Install Express.js

Express.js is the web framework for the node application. It will route the incoming http request to the proper destination to serve the static content. For more information on express please check the following link : http://expressjs.com/

Install express locally through npm in your project.

Rajas-MBP:node-static-page raja$ npm install express --save

Rajas-MBP:node-static-page raja$ cat package.json 
{
  "name": "node-static-page",
  "version": "1.0.0",
  "description": "Node Server to Serve Static Page",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "raja",
  "license": "ISC",
  "dependencies": {
    "express": "^4.16.2"
  }
}

--save will add the package information to package.json


Step-2

Add Static Page inside Public folder

Rajas-MBP:node-static-page raja$ ls
node_modules package.json

Rajas-MBP:node-static-page raja$ mkdir public
Rajas-MBP:node-static-page raja$ cd public

Rajas-MBP:public raja$ touch index.html

Add the basic html content inside index.html file present in public folder.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Served From Node</title>
</head>
<body>
    <h2>Hello World !! </h2>
</body>
</html>


Step-3

Create the node-js server

Rajas-MBP:node-static-page raja$ ls
node_modules package.json public

Rajas-MBP:node-static-page raja$ touch index.js


* Add the following lines inside index.js

var express = require('express');
var app = express(); // Create the express APP
var path = require('path'); //To Access the folder path

app.use(express.static(path.join(__dirname, 'public'))); //Express middleware

var server = app.listen(3200,function(){ //Server listening to port 3200
    console.log("We have started our server on port 3200");
});


Step-4

Start the server


Rajas-MBP:node-static-page raja$ node index.js 

We have started our server on port 3200


Visit localhost://3200



Note :

If you are interested to read few more node.js articles:

1) http://www.fullstacktechnos.com/2016/09/how-to-push-nodejs-app-to-heroku.html

2) http://www.fullstacktechnos.com/2017/09/how-to-update-nodejs-in-mac.html

Why we need firebase cloud functions ?

What is firebase ?

Firebase is the google cloud platform to build IOS, Android and Web apps. It takes care the infrastructure and backend for the app.

Following are the few important service that firebase provides.

1) Realtime Database
2) Authentication
3) Static Hosting
4) Cloud functions
5) Analytics
6) Storage

Why cloud functions ?

App can directly contact the services provided by firebase.
For ex: Your app can directly contact the realtime database for storing and retrieving data. This is called Database As Service.
You don't need to write your backend authentication logic as you can directly use the firebase authentication service to create, update and delete user. Firebase has support for Google, FB, Twitter, Github and normal email/password user login.

However if you want to perform certain actions when the event occurs from firebase features then you need the cloud functions.
Firebase cloud functions will listen to the events and trigger the custom functions.
For ex: If you want to send an welcome email once user is created you can write a cloud function which will listen to user creation and send an email when a new user is created.
You can move the client side logic which responds to the actions to the cloud functions so that same logic wont be repeated in your mobile and web app.
Third party API integration is now centralized using cloud functions.
Cloud functions works as a backend for your app.
You are actually not maintaining any backend server though google is running these functions in its own server. This is called serverless architecture.

Firebase cloud functions can respond to events generated by the following Firebase and Google Cloud features:

1) Cloud Firestore Triggers
2) Realtime Database Triggers
3) Firebase Authentication Triggers
4) Google Analytics for Firebase Triggers
5) Cloud Storage Triggers
6) Cloud Pub/Sub Triggers
7) HTTP Triggers


* Check the following article to create your 1st cloud function using firebase tool which will listen to the HTTP event.

http://www.fullstacktechnos.com/2017/10/introduction-to-cloud-functions-for.html


More Article :
http://www.fullstacktechnos.com/2017/10/firebase-authentication-service-for-web.html


Tuesday, October 17, 2017

Introduction to Cloud Functions for Firebase


Introduction to Cloud Functions for Firebase

* Before you start reading this if you want to know why we need cloud functions for firebase please check the following article: 
http://www.fullstacktechnos.com/2017/10/why-we-need-firebase-cloud-functions.html

Setup:

- Go to https://console.firebase.google.com and create a firebase project.
- Node and NPM should be installed in your local box.

Install Firebase Command Line Tools:

- Execute the following command in command line.

Rajas-MBP:Firebase raja$ sudo npm install -g firebase-tools
Rajas-MBP:Firebase raja$ firebase --version
3.13.1


Login to firebase from console :

- Create a project folder in you localbox called functions-firecast
- Enter inside the folder and login to firebase using CLI. Follow the command below.


Rajas-MBP:Firebase raja$ mkdir functions-firecast
Rajas-MBP:Firebase raja$ cd functions-firecast/
Rajas-MBP:functions-firecast raja$ firebase login
? Allow Firebase to collect anonymous CLI usage and error reporting information?
 Yes

- Browser will open, enter the same gmail account info using which you have created the project earlier
- Close the browser after completion of the steps.


Waiting for authentication...

✔  Success! Logged in as dummymailidtest@gmail.com


* Note : You will see your gmail id instead of dummymailidtest@gamil.com *


Initialize the Project:

In the command line enter into the project folder and run the following command.

Rajas-MBP:functions-firecast raja$ firebase init

- choose the project that you have created earlier as default project
- choose Functions to configure and deploy cloud functions.
- install dependancies using npm

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

✔  Firebase initialization complete!


Open the code in editor :

- Go to functions-firecast -> functions -> index.js and uncomment the "exports.helloworld" function.
- This http function will be triggered when there is a web request. It uses express framework of node.


Deploy the function:

- Run the following command in command line to deploy the function to google cloud under your project.


Rajas-MBP:functions-firecast raja$ firebase deploy

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/test123456/overview
Function URL (helloWorld): https://us-central1-test123456.cloudfunctions.net/helloWorld
Rajas-MBP:functions-firecast raja$


Check the content in browser :

- Open the URL https://us-central1-test123456.cloudfunctions.net/helloWorld in browser.
- You can find “Hello from Firebase!” in the browser

*Note-: Instead of test123456 you will see your project name*


Change the content and verify in browser  :

- Change "exports.hellowworld" function content as given below in index.js.


exports.helloWorld = functions.https.onRequest((request, response) => {
 response.send("Hello from Me !!");
 console.log("hello world function triggered !!");
});


- Save the code
- Go to console and deploy using command "firebase deploy" from your project folder.
- Refresh the browser.
- You can find the updated content !!


To find functions and Logs in Google Cloud :

- Go to the project page in google console. (https://console.firebase.google.com/project/test123456/functions/list)
- Go to the functions tab in left hand side panel.
- You can find the hello world functions in the dashboard and logs in the logs tab.
- You can see the console.log statement inside.


Summary:

- Setup

1) Create a firebase project at https://console.firebase.google.com
2) Node latest version should be installed
3) NPM latest version should be installed
4) Install firebase-tools using npm : 
    sudo npm install -g firebase-tools

- Run the following command to deploy cloud function from scratch :

1) Rajas-MBP:Firebase raja$ mkdir functions-firecast
2) Rajas-MBP:Firebase raja$ cd functions-firecast/
3) Rajas-MBP:functions-firecast raja$ firebase login

After Successful Login

4) Rajas-MBP:functions-firecast raja$ firebase init
5)  Rajas-MBP:functions-firecast raja$ firebase deploy

6) Go to the http endpoint URL in browser (for ex: https://console.firebase.google.com/project/test123456/functions/list)
You can find “Hello from Firebase!” in the browser


* Got to the https://firebase.google.com/docs/  and https://cloud.google.com/functions/ for more information *