Firebase cloud messaging với laravel 9

Đối với web truyền thống thì người dùng cần truy cập vào website để xem thông tin mà người dùng cần .Các admin thường không thể chủ động cung cấp những gì mới nhất đến với người cần xem .Do đó Firebase Cloud Messaging ra đời cung cấp dịch vụ này .  Bài viết này sẽ cung cấp cho các bạn 1 trong những cách cài đặt firebase lên web được code bằng Laravel 9

Tạo project app laravel :

1 Khởi tạo project laravel 9 firebase với lệnh sau :

composer create-project laravel/laravel firebase

Download packages hỗ trợ firebase cho php với lệnh sau :

composer require kreait/firebase-php

Tiếp theo chúng ta tạo controller xử lý firebase messaging như sau :

php artisan make:controller FcmController

Trong FcmController chúng ta code như sau :


namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Kreait\Firebase\Factory;
use Kreait\Firebase\Messaging\CloudMessage;

class FcmContrller extends Controller
{
    public function index()
    {
        return view('fcm');
    }
    public function runfcm(Request $request)
    {
        $fac = (new Factory())->withServiceAccount(resource_path('fir-lashare-firebase-adminsdk.json'));
        $mess = $fac->createMessaging();
        $message = CloudMessage::fromArray([
            'token'=>$request->token,
            'data' =>[
                'url'=>$request->link,
                'title'=>$request->title,
                'body'=>$request->body,
                'image'=>$request->image,
            ]
        ]);
        $mess->send($message);
        return back();
    }
}

Nhớ download file fir-lashare-firebase-adminsdk.json ở mục dưới ảnh về và lưu lại với tên đó

Ở phần view : ta tạo firebase/resources/views/fcm.blade.php như sau :

@extends('layouts.app')
@section('content')

    <form action="{{route('runfcm')}}" method="post">
        @csrf
        <div class="form-group">
            <label for="title">Title</label>
            <input type="text" name="title" value="Tiêu đề lashare" class="form-control" id="title" aria-describedby="title" placeholder="Title" required>
        </div>
        <div class="form-group">
            <label for="body">Body</label>
            <input type="text" name="body" value="Body lashare" class="form-control" id="body" aria-describedby="body" placeholder="Body" required>
        </div>
        <div class="form-group">
            <label for="token">Token : mặc định token của bạn ,bạn có thể điền token khác</label>
            <input type="text" name="token" class="form-control" id="token" aria-describedby="token" placeholder="token" required>
        </div>
        <div class="form-group">
            <label for="token">Link ảnh</label>
            <input type="text" name="image" value="https://lashare.info/images/Firebase_Push.png" class="form-control" id="image" aria-describedby="image" placeholder="Ảnh Notification" required>
        </div>

        <div class="form-group">
            <label for="token">Link</label>
            <input type="text" name="link" value="https://lashare.info/" class="form-control" id="link" aria-describedby="link" placeholder="link" required>
        </div>

        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
@endsection

 firebase/resources/views/layouts/app.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>Demo FCM</title>
    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    <!-- The core Firebase JS SDK is always required and must be listed first -->
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
    <script src="https://www.gstatic.com/firebasejs/8.3.2/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.3.2/firebase-messaging.js"></script>
    <script>
        // tự động gọi hàm khi load trang
        window.onload = function (){
            initFirebaseMessagingRegistration()
        };
        var firebaseConfig = {
            apiKey: "AIzaSyAQ4fb_ySwo4f23UFK74ixxVkWHpK2o***",
            authDomain: "fir-lashare.firebaseapp.com",
            projectId: "fir-lashare",
            storageBucket: "fir-lashare.appspot.com",
            messagingSenderId: "837040725327",
            appId: "1:837040725327:web:550cbb427a758fa9ce393a",
            measurementId: "G-ZHMYEXK998"
        };
        firebase.initializeApp(firebaseConfig);
        const messaging = firebase.messaging();
        function initFirebaseMessagingRegistration() {
            //thêm jquery nếu ko sẽ ko chạy
            messaging.requestPermission().then(
                function () {
                    return messaging.getToken()
                })
                .then(function (token) {
                    console.log(token)
                    navigator.serviceWorker.regi
                    if(document.getElementById("token_id"))
                    {
                        document.getElementById("token_id").innerHTML = token +''
                    }
                    if(document.getElementById("token"))
                    {
                        document.getElementById("token").value = token
                    }
                    $.ajaxSetup({
                        headers: {
                            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                        }
                    });
                }).catch(function (err) {
                console.log('User Chat Token Error' + err);
            });
        }

        // hiển thị khi đang trong trang web . nếu không ở trên trang web thì mới sử dụng server worok firebase-mesaging-sw
        messaging.onMessage((payload) => {
            console.log('Message received. ', payload.data);
            // ở đây chúng ta cần xử lý hàm data .Mọi thông tin truyền đi đều sử dụng data
            var message = payload.data;
            const Title = message.title;
            const content = {
                body: message.body ,
                icon: message.image,
                image: message.image,
            };
            //Click Event khi click vào notification
            var notificationUrl = message.url;
            var notificationObj = new Notification(Title,content);
            notificationObj.onclick = function () {
                notificationObj.close();
                window.open(notificationUrl);

            };
        });
    </script>
</head>
<body>

<div class="container">
    <!-- div to display messages received by this app. -->
    <div id="messages"></div>
    <!--
    <p id="token" style="word-break: break-all;"></p>
    -->
    @yield('content')
</div>
</body>
</html>

Ở router  firebase/routes/web.php chúng ta code như sau :

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/',[\App\Http\Controllers\FcmContrller::class,'index'])->name('home');
Route::post('/runfcm',[\App\Http\Controllers\FcmContrller::class,'runfcm'])->name('runfcm');

Các bạn nhớ up phần firebase/public/firebase-messaging-sw.js .

// Give the service worker access to Firebase Messaging.
 // Note that you can only use Firebase Messaging here. Other Firebase libraries
 // are not available in the service worker.
 importScripts('https://www.gstatic.com/firebasejs/9.2.0/firebase-app-compat.js');
 importScripts('https://www.gstatic.com/firebasejs/9.2.0/firebase-messaging-compat.js');
 // Initialize the Firebase app in the service worker by passing in
 // your app's Firebase config object.
 // https://firebase.google.com/docs/web/setup#config-object

 firebase.initializeApp({
    apiKey: "AIzaSyAQ4fb_ySwo4f23UFK74ixxVkWHpK2o***",
    authDomain: "fir-lashare.firebaseapp.com",
    projectId: "fir-lashare",
    storageBucket: "fir-lashare.appspot.com",
    messagingSenderId: "837040725327",
    appId: "1:837040725327:web:550cbb427a758fa9ce393a",
    measurementId: "G-ZHMYEXK998"
});
 // Retrieve an instance of Firebase Messaging so that it can handle background
 // messages.
 const messaging = firebase.messaging();


// If you would like to customize notifications that are received in the
// background (Web app is closed or not in browser focus) then you should
// implement this optional method.
// Keep in mind that FCM will still show notification messages automatically
// and you should use data messages for custom notifications.
// For more info see:
// https://firebase.google.com/docs/cloud-messaging/concept-options
messaging.onBackgroundMessage(function (payload) {
    console.log('[firebase-messaging-sw.js] Received background message ', payload.data);
    var notificationTitle = payload.data.title;
    var notificationOptions = {
        body: payload.data.body,
        icon: payload.data.icon,
        image: payload.data.image,
        action: payload.data.click_action
    };
    console.log("strated sending msg" + notificationOptions);
    return self.registration.showNotification(notificationTitle,notificationOptions);
});

self.addEventListener('notificationclick', function (event) {
    console.log('On notification click: ', event.notification);
    event.notification.close();
    var redirectUrl = null;
    if (event.notification.data) {
        if (event.notification.data.FCM_MSG) {
            redirectUrl = event.notification.data.FCM_MSG.data ? event.notification.data.FCM_MSG.data.click_action : null
        } else {
            redirectUrl = event.notification.data ? event.notification.data.click_action : null
        }
    }
    console.log("redirect url is : " + redirectUrl);

    if (redirectUrl) {
        event.waitUntil(async function () {
            var allClients = await clients.matchAll({
                includeUncontrolled: true
            });
            var chatClient;
            for (var i = 0; i < allClients.length; i++) {
                var client = allClients[i];
                if (client['url'].indexOf(redirectUrl) >= 0) {
                    client.focus();
                    chatClient = client;
                    break;
                }
            }
            if (chatClient == null || chatClient == 'undefined') {
                chatClient = clients.openWindow(redirectUrl);
                return chatClient;
            }
        }());
    }
});

self.addEventListener("notificationclose", function (event) {
    event.notification.close();
    console.log('user has clicked notification close');
});

Tiếp theo chúng ta dùng lệnh : 

php artisan serve

Truy cập link : https://127.0.0.1:8000 để tận hưởng kết quả

Github project demo ở link dưới các bạn có thể download về và tham khảo thêm