Connect Google Firebase with Modern Javascript

In this tutorial, we will be building step by step Javascript Application that connects to Google Firebase and performs the basic CRUD Operations all from scratch.

In our previous tutorial, we created the Javascript Recepie Application that connects to the Browser’s Local Storage, and as soon as we clear the local storage in the browser all the data we will loose. But now in this tutorial, we will connect to google firebase and it is completely free.




Tools and technologies used


  • Javascript
  • jQuery
  • Google firebase
  • Visual studio code
  • HTML
  • CSS
  • Bootstrap 4

Application features


  • Create a new todo
  • Filter todo’s
  • Complete/Incomplete todo’s
  • Hide completed todos
  • Remove todo

What we will build?


Below are the screenshots that show UI of our Simple Todo Application that we will create in this tutorial.

Application is running on the live server https://b2tech-todo-app.netlify.com/


Application development


First step is to Setup the google firebase in https://firebase.google.com. You can watch the below video to setup the google firebase.




Next step is to create index.html file and paste the firebase SDK, firebase-firestore.js script and get the reference to the firestore database.

    <script src="https://www.gstatic.com/firebasejs/7.2.2/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/7.2.2/firebase-firestore.js"></script>
    <script>
    var firebaseConfig = {
        apiKey: "<YOUR API KEY>",
        authDomain: "<YOUR AUTH DOMAIN>",
        databaseURL: "<YOUR DATABASE URL>",
        projectId: "<YOUR PROJECT ID>",
        storageBucket: "<YOUR STORAGE BUCKET>",
        messagingSenderId: "<YOUR MESSAGING SENDER ID>",
        appId: "<YOUR APP ID>",
        measurementId: "<YOUR MEASUREMENT ID>"
    };
    firebase.initializeApp(firebaseConfig);
    const db = firebase.firestore();
    </script>

NOTE: Make sure to use your firebase SDK and do not use mine

Next step is to include the jQuery library and UUID library for generating the unique id for storing the todo items in google firebase.

<script src="https://code.jquery.com/jquery-3.4.1.js"
    integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
    crossorigin="anonymous"></script>
<script src="http://wzrd.in/standalone/uuid%[email protected]"></script>

Next step is to create index.js custom script file and paste the following code

let todos = [];

const filters = {
    searchText: '',
    hideCompleted: false
}

$('.hidecheckbox').change(()=>{
    if($('.hidecheckbox').prop('checked')){
        hideCompleted(todos, filters);
    }else{
        createList(todos, filters);
    }
})

$('.search-todo').on('input', () => {
    filters.searchText = $('.search-todo').val();
    createList(todos, filters);
})

const createList = function (todos, filters) {
    let count = 0;
    const filteredTodos = $.grep(todos, element => {
        return element.todo.toLowerCase().includes(filters.searchText.toLowerCase());
    })
    $('.todos').empty();
    filteredTodos.forEach(singleTodo => {
        let divElement = $('<div>');
        divElement.addClass('form-check card singelTodo');
        let cardBodyElement = $('<div>');
        cardBodyElement.addClass('card-body');
        let labelElement = $('<label>');
        labelElement.addClass('form-check-label');
        let checkBoxElement = $('<input />');
        checkBoxElement.addClass('form-check-input');
        let buttonElement = $('<button>');
        buttonElement.addClass('float-right btn btn-primary');
        
        checkBoxElement.attr('type', 'checkbox');
        checkBoxElement.attr('checked', singleTodo.isCompleted);

        checkBoxElement.on('change', ()=>{
            toggleTodo(singleTodo);
        })

        labelElement.append(checkBoxElement);
        let paragraphElement = $('<span>');
        paragraphElement.text(singleTodo.todo);
        labelElement.append(paragraphElement);
        cardBodyElement.append(labelElement);
        buttonElement.text('X');
    
        buttonElement.on('click', ()=>{
            deleteTodo(singleTodo);
        })
        
        cardBodyElement.append(buttonElement);
        divElement.append(cardBodyElement);
        $('.todos').append(divElement);
        if(singleTodo.isCompleted == false){
            count++;
        }
    })
    $('.status').text('You have '+count+' todos left');
}

const renderTodos = function () {
    db.collection('todos').get().then(data => {
        data.docs.forEach(element => {
            const singleTodo = element.data();
            todos.push(singleTodo);
        });
        createList(todos, filters);
    }).catch(error=>{
        console.log('error occured', error);
    })
}

$('.todo-submit').click((event)=>{
    event.preventDefault();
    const id = uuidv4();
    const todo = {
        todo: $('.new-todo').val(),
        isCompleted: false,
        id: id
    }
    db.collection('todos').doc(id).set(todo).then(()=>{
        console.log('todo added successfully!');
        $('.new-todo').val('');
        todos.push(todo);
        createList(todos, filters);
    }).catch(error=>{
        console.log('error occured', e);
    })
})

const toggleTodo = function(singleTodo){
    const new_todo = {
        id: singleTodo.id,
        isCompleted: !singleTodo.isCompleted,
        todo: singleTodo.todo
    }   
    db.collection('todos').doc(singleTodo.id).update(new_todo).then(()=>{
        console.log('update successfully');
        singleTodo.isCompleted = !singleTodo.isCompleted;
        createList(todos, filters);
    }).catch(error=>{
        console.log('error occured', error);
    })
}

const deleteTodo = function (singleTodo) {
    db.collection('todos').doc(singleTodo.id).delete().then(()=>{
        console.log('todo deleted successfully');
        const todoIndex = todos.findIndex(todo =>todo.id === singleTodo.id);
        if(todoIndex != -1){
            todos.splice(todoIndex, 1);
            createList(todos, filters);
        }
    })
}

const hideCompleted = function(todos, filters){
    const filteredTodos = $.grep(todos, (element)=>{
        if (element.isCompleted == filters.hideCompleted) {
            return element;
        }
    })
    createList(filteredTodos, filters);
}

renderTodos();

Next step is to paste the following code inside the index.html file




<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" 
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <link rel="stylesheet" href="style.css">
    <title>Todo - Home</title>
</head>
<body>
    <div class="wrapper">
        <div class="content">
            <div class="row">
                <div class="text-center text-light bg-info col-md-12 col-12">
                    <h1>Todo Application</h1>
                    <p>Track todo's that never before</p> 
                </div>
            </div>
            <div class="search">
                <div class="container">
                    <form>
                        <div class="row">
                            <div class="col-md-4 col-8">
                                <input type="text" class="search-todo form-control" placeholder="Search todo" />
                            </div>
                            <div class="col-md-8 col-4 form-check checkbox">
                                <label class="form-check-label">
                                    <input type="checkbox" class="hidecheckbox form-check-input"/>Hide completed
                                </label>
                            </div>
                        </div>
                    </form>
                </div>
            </div> 
            
            <div class="container">
                
                <div class="row status-header">
                    <h5 class="status col-md-12 font-weight-bold text-danger"></h5>
                </div>
                <div class="todo-form">
                    <form>
                        <div class="row">
                            <div class="col-md-4 col-12">
                                    <input type="text" placeholder="Enter todo" class="new-todo form-control" required="true"/>
                            </div>
                            <div class="col-md-4 col-12">
                                <button type="submit" class="todo-submit btn btn-secondary">Add Todo</button>
                            </div>
                        </div>
                    </form>
                </div>
                <div class="row">
                    <div class="todos col-md-10 col-10"></div>
                </div>
            </div>
        </div>
        <div class="footer">
            <div class="container">
                <div class="row">
                    <div class="col-md-12 col-10">
                        <p>Designed and Developed by Bushan Sirgur (c) <a href="https://bushansirgur.in">B2 Tech</a></p>
                    </div>
                </div>  
            </div>
        </div>
    </div>
    <script src="https://www.gstatic.com/firebasejs/7.2.2/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/7.2.2/firebase-firestore.js"></script>
    <script>
    var firebaseConfig = {
        apiKey: "AIzaSyC5_qmnte1ZjzeuNqt6Wdo4eL2EiBMsosQ",
        authDomain: "b2tech-todo-app.firebaseapp.com",
        databaseURL: "https://b2tech-todo-app.firebaseio.com",
        projectId: "b2tech-todo-app",
        storageBucket: "b2tech-todo-app.appspot.com",
        messagingSenderId: "428612265502",
        appId: "1:428612265502:web:f0db25fc678f41d0e4f00f",
        measurementId: "G-WN2ZJVFKZW"
    };
    firebase.initializeApp(firebaseConfig);
    const db = firebase.firestore();
    </script>
    <script src="https://code.jquery.com/jquery-3.4.1.js"
    integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
    crossorigin="anonymous"></script>
    <script src="http://wzrd.in/standalone/uuid%[email protected]"></script>
    <script src="index.js"></script>
</body>
</html>

Next step is to create style.css custom css file and paste the following code

.search{
    background-color: #DAE0E2;
    height: 4em;
}
.checkbox{
    margin-top: 0.5%;
}
.singelTodo{
    margin-bottom: 1%;
}
.status-header{
    margin-top: 1%;
    margin-bottom: 1%;
}
.todo-form{
    margin-bottom: 1%;
}
.search-form{
    margin-top: 1%;
    margin-bottom: 1%;
}
.search div form{
    padding-top: 1em;
}
a:hover{
    text-decoration: none;
}
body, html{
    height: 100%;
}
.footer{
    position: absolute;
    bottom: 10px;
    height: 60px;
}
.wrapper{
    min-height: 100%;
    position: relative;
}
.content{
    padding-bottom: 100px;
}

Run the application


Open the index.html file in a browser to run the application.

This completes the Javascript Todo Application. If you have any queries regarding this tutorial you can reach out – [email protected]




Watch the complete video course


 

Love this post?


Help me to buy a cup of coffee/Support us by donating.
All the donations will be going to the website maintenance/improvement.

Pay Now

Happy coding!

About the author

Bushan Sirgur

Well, I am Bushan Sirgur from Banglore, India. Currently, I am working as a Software Developer in a Service Base Company. I am interested in JAVA/J2EE, Angular 2, JavaScript, jQuery, MongoDB.

View all posts

Leave a Reply

Your email address will not be published. Required fields are marked *