Laravel 8 Realtime CRUD operation example using Google Firebase

CRUD operation is a basic part of any web application. When you implement CRUD operation in user side, it will provide smooth and better user experience to user. There are currently many 3rd party provides free realtime database. You don't need to install Redis or node application to run application realtime.

In this article, We will go through implment realtime CRUD operation in Laravel 8 using Google Firebase. We will create post module in the Laravel application. We will go through step by step from the scratch to implement CRUD operation.

  • Step 1: Create Firebase account and authentication
  • Step 2: Create Laravel application.
  • Step 3: Create post route
  • Step 4: Create new controller
  • Step 5: Configure firebase setting in Laravel application
  • Step 6: Create blade view
  • Step 7: Run Laravel application and test

So let's start from creating Firebase account.

Step 1: Create Firebase account and authentication

In the first step, we create a Google Firebase account and get a config file. First of all create account at Google Firebase using Google account.

In the Google Firebase account, we will need to create realtime database and get configuration details.

For that, add Firebase account to Web application from dashboard and copy the below configuration options somewhere. We will use this in the Laravel blade view.

const firebaseConfig = {
    apiKey: "AIzaS...............GhWlyDY",
    authDomain: "crud-66568.firebaseapp.com",
    projectId: "crud-66568",
    databaseURL: 'crud-66568.firebaseio.com',
    storageBucket: "crud-66568.appspot.com",
    messagingSenderId: "6399947556078",
    appId: "1:6399947556078:web:6a97ecddf7s4dsw5e10f"
};

Step 2: Create Laravel application.

In the second step, we will create Laravel application using Composer. So open Terminal or CMD and run the below command from application folder.

composer create-project --prefer-dist laravel/laravel crud

Change Terminal current directory to project using cd command.

cd crud

Step 3: Create post route

In the third step, we create post route which will show post module. Laravel routes are located at routes/web.php file. Open the file and add below route in it.

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

Route::get('post', [PostController::class, 'index'])->name('post.inedx');

Step 4: Create new controller

We will need controller class and method which will return HTML view when user go to the post route. So create controller class using artisan command.

php artisan make:controller PostController

After creating controller, open it from app/Http/Controllers/PostController.php file and add index class method which will return Laravel blade view.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostController extends Controller
{
    /**
     * Display a listing of the post.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('index');
    }
}

Step 5: Configure firebase setting in Laravel application

Instead of putting Firebase credentials direct into blade view, we will put it into config file and fetch it to the blade view. That way, we can use all these details at anywhere into project. All external services credentials are stored at config/services.php file. So open services.php file and add below firebase array into it.

'firebase' => [
    'api_key' => 'AIzaS...............GhWlyDY',
    'auth_domain' => 'crud-66568.firebaseapp.com',
    'database_url' => 'crud-66568.firebaseio.com',
    'project_id' => 'crud-66568',
    'storage_bucket' => 'crud-66568.appspot.com',
    'messaging_sender_id' => '6399947556078',
    'app_id' => '1:6399947556078:web:6a97ecddf7s4dsw5e10f',
    'measurement_id' => 'G-892WNWRCBP',
],

You can even store Firebase details at .env file and fetch use env() method to fetch any details from .env file.

Step 6: Create blade view

Now the important part of crud operation is setting up view file. Laravel views are located at resources/views folder. So create new blade view index.blade.php and put the below code into it.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>CRUD Operation</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
    <div class="container">
        <h1 class="m-3">CRUD Operation</h1>
        <div class="row">
            <div class="col-12">
                <div class="card">
                    <div class="card-header">
                        ALL Post
                        <div class="float-end">
                            <button type="button" class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#add-modal">Add post</button>
                        </div>
                    </div>
                    <div class="card-body">
                        <table class="table table-hover">
                            <thead>
                                <tr>
                                    <th scope="col">#</th>
                                    <th scope="col">Title</th>
                                    <th scope="col">Content</th>
                                    <th scope="col">Action</th>
                                </tr>
                            </thead>
                            <tbody id="table-list">
                                
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
    {{-- create modal --}}
    <div class="modal fade" id="add-modal" tabindex="-1">
        <div class="modal-dialog modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Create post</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" ></button>
                </div>
                <div class="modal-body">
                    <form id="add-post" method="post">
                        <div class="mb-3">
                            <label for="title" class="form-label">Title</label>
                            <input type="text" class="form-control" id="title" name="title">
                        </div>
                        <div class="mb-3">
                            <label for="content" class="form-label">Content</label>
                            <textarea class="form-control" id="content" name="content"></textarea>
                        </div>
                        <button type="button" id="add-submit" class="btn btn-primary">Submit</button>
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
    {{-- update modal --}}
    <div class="modal fade" id="update-modal" tabindex="-1">
        <div class="modal-dialog modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Update post</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <form id="update-post" method="post">
                        <div class="mb-3">
                            <label for="update-title" class="form-label">Title</label>
                            <input type="text" class="form-control" name="title" id="update-title" >
                        </div>
                        <div class="mb-3">
                            <label for="update-content" class="form-label">Content</label>
                            <textarea class="form-control" name="content" id="update-content"></textarea>
                        </div>
                        <button type="button" id="update-button" class="btn btn-primary">Submit</button>
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
    {{-- delete modal --}}
    <div class="modal fade" id="delete-modal" tabindex="-1">
        <div class="modal-dialog modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Delete post</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <p class="lead">Are you sure you want to delete this post?</p>
                    <input name="id" id="post-id" type="hidden">
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                    <button type="button" id="delete-button" class="btn btn-primary">Delete</button>
                </div>
            </div>
        </div>
    </div>
    <script src="https://www.gstatic.com/firebasejs/8.0.0/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.0.0/firebase-database.js"></script>
    <script type="text/javascript">
        // Your web app's Firebase configuration
        const firebaseConfig = {
            apiKey: "{{ config('services.firebase.api_key') }}",
            authDomain: "{{ config('services.firebase.auth_domain') }}",
            databaseURL: "{{ config('services.firebase.database_url') }}",
            projectId: "{{ config('services.firebase.project_id') }}",
            storageBucket: "{{ config('services.firebase.storage_bucket') }}",
            messagingSenderId: "{{ config('services.firebase.messaging_sender_id') }}",
            appId: "{{ config('services.firebase.app_id') }}"
        };

        // Initialize Firebase
        const app = firebase.initializeApp(firebaseConfig);

        var database = firebase.database();

        var lastId = 0;
        
        // get post data
        database.ref("posts").on('value', function(snapshot) {
            var value = snapshot.val();
            var htmls = [];
            $.each(value, function(index, value){
                if(value) {
                    htmls.push('<tr>\
                        <td>'+ index +'</td>\
                        <td>'+ value.title +'</td>\
                        <td>'+ value.content +'</td>\
                        <td><a data-bs-toggle="modal" data-bs-target="#update-modal" class="btn btn-success update-post" data-id="' + index + '">Update</a>\
                        <a data-bs-toggle="modal" data-bs-target="#delete-modal" class="btn btn-danger delete-data" data-id="' + index + '">Delete</a></td>\
                    </tr>');
                }       
                lastId = index;
            });
            $('#table-list').html(htmls);
        });

        // add data
        $('#add-submit').on('click', function() {
            var formData = $('#add-post').serializeArray();
            var createId = Number(lastId) + 1;

            firebase.database().ref('posts/' + createId).set({
                title: formData[0].value,
                content: formData[1].value,
            });

            // Reassign lastID value
            lastId = createId;
            $("#add-post")[0].reset();
            $("#add-modal").modal('hide');
        });

        // update modal
        var updateID = 0;
        $('body').on('click', '.update-post', function() {
            updateID = $(this).attr('data-id');
            firebase.database().ref('posts/' + updateID).on('value', function(snapshot) {
                var values = snapshot.val();
                $('#update-title').val(values.title);
                $('#update-content').val(values.content);
            });
        });

        // update post
        $('#update-button').on('click', function() {
            var values = $("#update-post").serializeArray();
            var postData = {
                title : values[0].value,
                content : values[1].value,
            };

            var updatedPost = {};
            updatedPost['/posts/' + updateID] = postData;

            firebase.database().ref().update(updatedPost);

            $("#update-modal").modal('hide');
            $("#update-post")[0].reset();
        });

        // delete modal
        $("body").on('click', '.delete-data', function() {
            var id = $(this).attr('data-id');
            $('#post-id').val(id);
        });

        // delete post
        $('#delete-button').on('click', function() {
            var id = $('#post-id').val();
            firebase.database().ref('posts/' + id).remove();

            $('#post-id').val('');
            $("#delete-modal").modal('hide');
        });
    </script>
</body>
</html>

Explanation

  • We used Bootstrap to create responsive table view.
  • In the bottom Javascript code, we included Firebase CDN files.
  • Initialized Firebase app using configuration:
const firebaseConfig = {
    apiKey: "{{ config('services.firebase.api_key') }}",
    authDomain: "{{ config('services.firebase.auth_domain') }}",
    databaseURL: "{{ config('services.firebase.database_url') }}",
    projectId: "{{ config('services.firebase.project_id') }}",
    storageBucket: "{{ config('services.firebase.storage_bucket') }}",
    messagingSenderId: "{{ config('services.firebase.messaging_sender_id') }}",
    appId: "{{ config('services.firebase.app_id') }}"
};

const app = firebase.initializeApp(firebaseConfig);
var database = firebase.database();
  • To get data from Firebase, we used firebase.database().ref('posts') method. This will return post collection.
  • We used Bootstrap modal to open create and update form.
  • We used firebase.database().ref().set() method to create post data.
  • Same way we used update() and remove() method to update and delete data. Notice how we are passing collection index in ref() method to get, update and delete post data.

Step 7: Run Laravel application and test

Our coding part is done. Now in the last step, we will run Laravel application and test it. Run the below command into Terminal.

php artisan serve

In your browser, go to the url http://localhost:8000/post. If everything goes as per tutorial, you will see below view. For the debugging errors, open console tab from the developer tool. 

Now try to create, update and delete post.

Conclusion

In this tutorial article, we created Google Firebase account and used realtime database in Laravel 8 application. I hope this article will help you creating awesome app. If you liked this article, like our Facebook page and follow us on Twitter.