Hướng dẫn gửi push notification laravel firebase

  • June 23, 2020
  • 6782

Bạn đang không biết làm thế nào để gửi push notification cho app androi, ios thì đây chính là bài viết dành cho bạn. Mình sẽ hướng dẫn các bạn xây dược thư viện để gửi push notification sử dụng firebase và laravel.

Làm thế nào để gửi push notification

Firebase cung cấp dịch vụ gửi push noti miễn phí Firebase Cloud Messaging Server (FCM). FCM sẽ nhận messages từ server và gửi message đến các app đang chạy theo device_token. Device token được sinh ra từ lần đầu cài app, server sẽ lưu device_token  user khi nào cần gửi notifi cho user thì sẽ bắn theo token đó. Thật tuyệt vời khi firebase đảm bảo được việc device token này là unique. Device token được lưu vào bảng channels

+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| id           | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| user_id      | bigint(20) unsigned | YES  | MUL | NULL    |                |
| device_token | varchar(255)        | NO   |     | NULL    |                |
| device_id    | varchar(255)        | YES  | MUL | NULL    |                |
| device_type  | varchar(25)         | NO   |     | ios     |                |
| active       | tinyint(1)          | NO   | MUL | 1       |                |
| created_at   | timestamp           | YES  |     | NULL    |                |
| updated_at   | timestamp           | YES  |     | NULL    |                |
+--------------+---------------------+------+-----+---------+----------------+

Hướng dẫn gửi push với laravel

Tạo một FCM service

 App/Service/FCMService.php


<?php

namespace App\Services;

use GuzzleHttp\Client;
use Log;

class FCMService
{

    private $apiConfig;

    public function __construct()
    {
        $this->apiConfig = [
            'url' => config('firebase.push_url'),
            'server_key' => config('firebase.server_key'),
            'device_type' => config('firebase.device_type')
        ];
    }

    /**
     * Sending push message to single user by Firebase
     *
     * @param string $device_token
     * @param array $notification
     * @param array $data
     *
     * @return bool|string
     */
    
    public function send(string $device_token, array $notification, array $data)
    {
        if ($data['device_type'] === $this->apiConfig['device_type']['ios']) {
            $fields = [
                'to'   => $device_token,
                'notification' => $notification,
                'data' => $data
            ];
        } else {
            $fields = [
                'to'   => $device_token,
                'data' => array_merge($data, $notification)
            ];
        }

        return $this->sendPushNotification($fields);
    }

    /**
     * Sending push message to multiple users by firebase
     * @param array $device_tokens
     * @param array $notification
     * @param array $data
     *
     * @return bool|string
     */
    public function sendMultiple(array $device_tokens, array $notification, array $data)
    {
        $fields = [
            'registration_ids' => $device_tokens,
            'data' => $data,
            'notification' => $notification
        ];

        return $this->sendPushNotification($fields);
    }

    /**
     * GuzzleHTTP request to firebase servers
     * @param array $fields
     *
     * @return bool
     */
    private function sendPushNotification(array $fields)
    {
        $client = new Client([
            'headers' => [
                'Content-Type' => 'application/json',
                'Authorization' => 'key='. $this->apiConfig['server_key'],
            ]
        ]);
        $res = $client->post(
            $this->apiConfig['url'],
            ['body' => json_encode($fields)]
        );
// Request api fcm by json data
// $res = $client->post($this->apiConfig['url'], json_encode($fields), ['type' => 'json']);
$res = json_decode($res->getBody()); if ($res->failure) { Log::error("ERROR_PUSH_NOTIFICATION: ".$fields['to']); } return true; } }

Tạo một fire config

Chứa các thông tin liên quan đến filebase

config/firebase.php


<?php

return [
    'push_url' => 'https://fcm.googleapis.com/fcm/send',
    'server_key' => env('FIREBASE_SERVER_KEY', null), // Lấy trong tài khoản firebase
    'device_type' => [
        'ios' => 'iOS',
        'android' => 'android'
    ],
    'sound' => 'default'
];

Viết một traist để gửi push

App/Traists/PushNotificationTraist.php


<?php

namespace App\Traits;

use App\Services\FCMService;

trait PushNotificationTrait
{
    public function pushMessage(string $deviceToken, array $notification, array $data)
    {
        $pushNotificationService = new FCMService();
return $pushNotificationService->send($deviceToken, $notification, $data); } public function pushMessages(array $deviceTokens, array $notification, array $data) { $pushNotificationService = new FCMService();
return $pushNotificationService->sendMultiple($deviceTokens, $notification, $data); } }

Viết controller để gửi push notification

Cuối cùng chúng ta hãy tận hưởng thành quả của mình, tạo 1 controller để gửi push notification App/Http/Controllers/NotificationController.php

<?php

namespace App\Http\Controllers;

use App\Traits\PushNotificationTrait;

class HomeController extends Controller
{

    use PushNotificationTrait;

    public function sendPush()
    {
           $totalUnread = 1;
           $data = [
                'func_name' => config('firebase.notification.func'),
                'screen' => config('firebase.notification.screen'),
                'total_unread' => $totalUnread,
                'total_count' => 2,
                'device_type' => 'ios', // Loại device, có thể là androi, web, ios
            ];
            $content = [
                "title" => "hello", // tiêu đề tin nhắn
                "body" => "test", // nội dung tin nhắn
                'badge' => $totalUnread, // số message chưa đọc
                'sound' => config('firebase.sound') // âm báo tin nhắn
            ];

            // Push notification
            $this->pushMessage($deviceToken, $content, $data);
    }
}

Trên đây là toàn bộ hướng dẫn về push notification với FCM thông qua laravel. Chúc ae nhận được notification tinh tinh nhé :D.

Hiện tại firebase không còn support gửi push notification sử dụng http protocol nữa. Các bạn chuyển qua sử dụng firebase sdk nhé. Tham khảo viết bài hướng dẫn gửi firebase push notioncation sử dụng firebase sdk.

Document: Firebase Cloud Messaging HTTP protocol