向用户发送大量通知 - Laravel

问题描述 投票:0回答:1

我想在 Laravel 中发送大量通知。

通知方法是 firebase,我正在使用 kutia-software-company/larafirebase 包作为 Not济。

目前,我大约有 10000 个 fcm,但我想将发送通知优化为 100000 个 fcm。

我实现了如下系统:

首先,我创建了一个可通知的类,如包中所述

<?php

namespace Vendor\Core\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Kutia\Larafirebase\Messages\FirebaseMessage;

class FirebasePushNotification extends Notification
{
    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct(protected $title, protected $message, protected array $fcmTokens = [])
    {
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param mixed $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['firebase'];
    }

    public function toFirebase($notifiable)
    {
        return (new FirebaseMessage)
            ->withTitle($this->title)
            ->withBody($this->message)
            ->withPriority('high')
            ->asNotification($this->fcmTokens);
    }
}

其次,创建通知作业:

<?php

namespace Vendor\PushNotification\Jobs;

use Vendor\Core\Notifications\FirebasePushNotification;
use Vendor\Customer\Contracts\UserDeviceInfo;
use Vendor\Customer\Contracts\Customer;
use Illuminate\Bus\Batchable;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Notification;


class SendPushNotificationJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, Batchable;

    public function __construct(public string $title, public string $body, public Customer $customer, public UserDeviceInfo $userDeviceInfo)
    {
    }

    public function handle()
    {
        Notification::send($this->customer, new FirebasePushNotification($this->title, $this->body, [$this->userDeviceInfo->fcm]));
    }

}

并使用

Bus::dispatch
将作业发送到队列:

        $usersDeviceInfos = $usersDeviceInfos->with('customer')->get();

        $bus = [];
        for ($i = 0; $i < 100000; $i++){
            foreach ($usersDeviceInfos as $usersDeviceInfo) {

                $bus [] = new SendPushNotificationJob($data['notification_title'], $data['notification_body'], $usersDeviceInfo->customer, $usersDeviceInfo);
            }
        }

        Bus::batch($bus)->name('push notification' . now()->toString())->dispatch();

目前,由于开发环境的原因,我只有一个fcm并使用循环来模拟10000,运行此代码需要一分多钟的时间,并且我会得到最大执行错误。

另外,请注意,我配置了我的队列,但它不是

sync
,我检查了这两个问题,但没有帮助:

希望找到一种更快的方法来批处理这些作业并将它们发送到队列

laravel firebase notifications queue
1个回答
0
投票

我找到了一个解决方案,可以在几秒钟内处理发送多达一百万个 fcm 的通知

我决定使用

kreait/laravel-firebase
并使用这里提到的多播

首先我对 fcms 进行分块,然后使用 A 作业并将它们分派到队列中。

这是解决方案的示例:

<?php

namespace Vendor\PushNotification\Jobs;

use Illuminate\Bus\Batchable;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Laravel\Firebase\Facades\Firebase;

class SendPushNotificationJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, Batchable;

    public function __construct(public string $title, public string $body, public array $fcmTokens)
    {
    }

    public function handle()
    {
        $message = CloudMessage::fromArray(YOUR_DATA);
        Firebase::messaging()->sendMulticast($message, $this->fcmTokens);
    }

}
        $chunks = $usersDeviceInfos->with('customer')->get()->pluck('fcm')->chunk(500);

        foreach ($chunks as $chunk) {
            dispatch(new SendPushNotificationJob($data['notification_title'], $data['notification_body'], $chunk->toArray()));
        }
© www.soinside.com 2019 - 2024. All rights reserved.