I have a single page application. I use a vuejs as a front-end and laravel 5.7 as a backend. I'm using a webPush and service worker to push notifications to users. The problem is when the user is offline and return back online a lot of notifications are pushed. I need to push only the last notifications in service worker queue and the number of other notifications in the queue.
//Listen to Push from service worker file
self.addEventListener('push', (e) => {
let data
if (e.data) {
data = e.data.json()
}
const options = {
body: data.body,
icon: '/images/fav/android-icon-192x192.png',
image: '/storage/users'+data.image||'/images/profiles/profile.png',
badge: '/images/fav/android-icon-96x96.png',
actions:data.actions,
data:data.data
}
e.waitUntil(self.registration.showNotification(data.title, options))
});
self.addEventListener('notificationclick', function(event) {
var url = event.notification.data.location;
event.waitUntil(
clients.matchAll({type: 'window'}).then( windowClients => {
for (var i = 0; i < windowClients.length; i++) {
var client = windowClients[i];
if (client.url === url && 'focus' in client) {
return client.focus();
}
}
if (clients.openWindow) {
return clients.openWindow(url);
}
})
);
});
//User model
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;
use NotificationChannels\WebPush\HasPushSubscriptions;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
use HasPushSubscriptions;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'fname','lname',"username", 'email', 'password',"code","active"
];
protected $guard_name = 'api';
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
// Rest omitted for brevity
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* #return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* #return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
//example for notification class
<?php
namespace App\Notifications;
use App\PostEvent;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use NotificationChannels\WebPush\WebPushChannel;
use NotificationChannels\WebPush\WebPushMessage;
class interestEvent extends Notification implements ShouldQueue
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public $event;
public $user;
public function __construct(PostEvent $event,User $user)
{
$this->event=$event;
$this->user=$user;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['database','broadcast',WebPushChannel::class];
}
public function toDatabase($notifiable)
{
$message="event you are interested in will begin tomorrow";
$name=$this->user->fname;
if($name){
$name .=" ".$this->user->lname;
}
else
{
$name=$this->user->username;
}
return [
'user_id' => $this->user->id,
"name"=>$name,
'message' => $message,
'image'=>$this->user->image,
'post_id'=>$this->event->post_id,
'eventName'=>$this->event->name,
];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
$message="event you are interested in will begin tomorrow";
$name=$this->user->fname;
if($name){
$name .=" ".$this->user->lname;
}
else
{
$name=$this->user->username;
}
return [
'id' => $this->id,
'read_at' => null,
'data' => [
'user_id' => $this->user->id,
'message' => $message,
"name"=>$name,
'image'=>$this->user->image,
'post_id'=>$this->event->post_id,
'eventName'=>$this->event->name,
'location'=>"/home/posts/".$this->event->post_id
],
];
}
public function toWebPush($notifiable, $notification)
{
$message="event you are interested in will begin tomorrow";
$name=$this->user->fname;
if($name){
$name .=" ".$this->user->lname;
}
else
{
$name=$this->user->username;
}
$message="(".$this->event->name.") ".$message;
return (new WebPushMessage)
->title('Ajwbtcom')
->body($message)
->action('See Event', "/home/posts/".$this->event->post_id)
->image($this->user->image)
->data( [
'user_id' => $this->user->id,
'message' => $message,
"name"=>$name,
'image'=>$this->user->image,
'post_id'=>$this->event->post_id,
'eventName'=>$this->event->name,
'location'=>"/home/posts/".$this->event->post_id
]);
}
}
You can use the tag option when you call showNotification in order to display only the last notification:
https://notifications.spec.whatwg.org/#using-the-tag-member-for-a-single-instance
Related
I'm not sure if I'm overcomplicating events/listeners/notifications in Laravel, but it feels like maybe I am, and I'm getting some unexpected results, although technically it's working.
My basic structure is this:
MonthlySummaryCompletedEventis fired.
The HandleMonthlySummaryCompletedEvent listener listens for the event.
It triggers a SendMonthlySummaryCreatedNotification notification.
This is all working (locally at least), except for 2 things:
I've had to put in a 5 second sleep in my livewire component that receives the notification because of timing issues. It almost seems like the pusher notification arrives before the notification has been written to the database.
It appears that 2 messages are sent to pusher:
Here's the code for my event:
class MonthlySummaryCompletedEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public User $requestedBy;
public string $fileDownloadUrl;
public string $fileName;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($event, string $fileDownloadUrl, string $fileName)
{
$this->requestedBy = $event->requestedBy;
$this->fileDownloadUrl = $fileDownloadUrl;
$this->fileName = $fileName;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('users.' . $this->requestedBy->id);
}
}
here's the code for my listener:
class HandleMonthlySummaryCompletedEvent implements ShouldQueue
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param object $event
* #return void
*/
public function handle($event)
{
Notification::send($event->requestedBy, new SendMonthlySummaryCreatedNotification($event));
}
}
and here's the code for the notification:
class SendMonthlySummaryCreatedNotification extends Notification implements ShouldQueue, ShouldBroadcast
{
use Queueable;
public $fileDownloadUrl;
public $fileName;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($event)
{
$this->fileDownloadUrl = $event->fileDownloadUrl;
$this->fileName = $event->fileName;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['database', 'broadcast'];
}
/**
* Get the broadcastable representation of the notification.
*
* #param mixed $notifiable
* #return BroadcastMessage
*/
public function toBroadcast($notifiable)
{
Log::debug($notifiable->toArray());
return new BroadcastMessage([
'title' => 'Monthly Summary Complete',
'message' => "{$this->fileName} is ready. ",
'link' => $this->fileDownloadUrl,
'link_text' => 'Click here to download',
'show_toast' => true,
'user_id' => $notifiable->id
]);
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toDatabase($notifiable)
{
return [
'title' => 'Monthly Summary Complete',
'message' => "{$this->fileName} is ready. ",
'link' => $this->fileDownloadUrl,
'link_text' => 'Click here to download',
'show_toast' => true,
'user_id' => $notifiable->id
];
}
}
And here's my front end livewire component:
public function getListeners()
{
return [
"echo-private:users.{$this->user->id},StatementCompleted" => 'notifyUser',
"echo-private:users.{$this->user->id},MonthlySummaryCompletedEvent" => 'notifyUser',
];
}
public function mount()
{
$this->user = Auth::user();
$this->refreshNotifications();
$this->showNotificationsBadge = ($this->notificationCount > 0) ? true : false;
}
public function render()
{
return view('livewire.components.notifications');
}
public function notifyUser()
{
$this->showNotificationsBadge = true;
sleep(5);
$this->refreshNotifications();
$message = $this->notifications->first()->data['message'];
if (isset($this->notifications->first()->data['show_toast']) && $this->notifications->first()->data['show_toast'] == true) {
$this->dispatchBrowserEvent('triggerToast', [Helper::notification('Success', $message)]);
}
}
I've implemented pusher beams like this:
I've added credentials in config/services.php
'pusher' => [
'beams_instance_id' => '********',
'beams_secret_key' => '*************',
],
I've created a new notification
class TestOne extends Notification
{
use Queueable;
public $message;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($message)
{
$this->message = $message;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return [PusherChannel::class , 'database'];
}
/**
* Get the array representation of the notification.
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
// event( new PostLiked($notifiable->id ,$this->message));
return [
'title' => $this->message->title,
'content' => $this->message->content,
];
}
// notification type
public function broadcastType()
{
return 'users';
}
public function toPushNotification($notifiable)
{
return PusherMessage::create()
->platform('web')
->badge(1)
->sound('success')
->body("Your ac account was approved!");
}
}
I've added Notifiable to User Model :
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
How to specify the interest in my backend so I can listen to it in my react app and how to use beams debug console to make sure the Laravel notification is being fired?
public function toPushNotification($notifiable)
{
return PusherMessage::create()
->platform('web')
->badge(1)
->sound('success')
->body("Your ac account was approved!");
}
While I was tracking this code , It seems that I had a certificate issues problem in my local environment.
So I moved to this way in connection to beams :
$beamsClient = new \Pusher\PushNotifications\PushNotifications(array(
"instanceId" => "*********************************",
"secretKey" => "***************",
), new GuzzleHTTP\Client(['verify' => false]));
$publishResponse = $beamsClient->publishToUsers(
array("user-001", "user-002", "1"),
array("web" => array("notification" => array(
"title" => "fofo",
"body" => "Hello, World!",
"deep_link" => "https://www.pusher.com",
)),
));
I've created a broadcast channel App.Models.Admin.Notify where all the admin users will be subscribed to this channel by default.
<?php
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('App.Models.Admin.Notify', function ($m) {
return !is_null($m) && $m->getMorphClass() === 'admin';
});
And this is the Notifications/Base.php where i've set ['database', 'broadcast', OneSignal::class] as notification channels
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Notifications\Messages\BroadcastMessage;
use NotificationChannels\OneSignal\OneSignalMessage;
use App\Channels\OneSignal;
abstract class Base extends Notification implements ShouldBroadcast, ShouldQueue
{
use Queueable;
public $model;
protected string $icon;
public function __construct(mixed $m = null)
{
$this->model = $m;
}
/**
* Get notify id
*
* #return string
*/
protected function getNotifyId(): string
{
return $this->id;
}
/**
* Get icon path
*
* #return string
*/
protected function getIcon(): string
{
return asset('favicon.ico');
}
/**
* Get notification link
*
* #return string
*/
protected function getLink(): string
{
return asset('favicon.ico');
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return \App\Channels\PusherBeams\PusherMessage
*/
public function via($notifiable)
{
return [
'database',
'broadcast',
OneSignal::class
];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return array_merge(
[
'link' => $this->getLink(),
'icon' => $this->getIcon(),
],
$this->getData($notifiable)
);
}
/**
* Get data of message.
*
* #param mixed $notifiable
* #return array
*/
protected function getData($notifiable)
{
return [
'title' => 'hello',
'body' => 'world'
];
}
/**
* Create onesignal message of Web
* #param mixed $notifiable
* #return \NotificationChannels\OneSignal\OneSignalMessage
*/
public function toWeb($notifiable)
{
$data = $this->toArray($notifiable);
return OneSignalMessage::create()
->setSubject($data['title'])
->setBody($data['body'])
->setUrl($data['link']);
}
/**
* Create onesignal message of Android
* #param mixed $notifiable
* #return \NotificationChannels\OneSignal\OneSignalMessage
*/
public function toAndroid($notifiable)
{
$data = $this->toArray($notifiable);
return OneSignalMessage::create()
->setSubject($data['title'])
->setBody($data['body'])
->setData('url', str_replace('https://', 'gamepts://', $data['link']));
}
/**
* Websocket message
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\BroadcastMessage
*/
public function toBroadcast($notifiable)
{
return (new BroadcastMessage($this->toArray($notifiable)))->onQueue('pusher');
}
}
So this is the basic setup for my Notifications and broadcasting.
I've a job which runs every minutes and if any reports are found then it should send the notification if any reports are found.
<?php
namespace App\Console\Commands;
use Carbon\Carbon;
use App\Models\MerchantDeposit;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Notification;
class CheckCashIn extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'check:cashin';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Check expiration of cash in orders';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$setting = app(\App\Settings\CurrencySetting::class)->currency;
$expired_limit = app(\App\Settings\AdminSetting::class)->expired_payin_limit_notify;
$reports = [];
foreach ($setting as $currency => $s) {
$expired_minutes = $s['expired_minutes'];
$k = MerchantDeposit::where('status', MerchantDeposit::STATUS['PENDING'])
->where('currency', $currency)
->where('created_at', '<=', Carbon::now()->subMinutes($expired_minutes))
->update(['status' => MerchantDeposit::STATUS['EXPIRED']]);
$o = MerchantDeposit::where('merchant_deposits.status', MerchantDeposit::STATUS['EXPIRED'])
->join('reseller_bank_cards', 'reseller_bank_cards.id', 'merchant_deposits.reseller_bank_card_id')
->join('resellers', 'resellers.id', 'reseller_bank_cards.reseller_id')
->where('merchant_deposits.currency', $currency)
->where('merchant_deposits.created_at', '<=', Carbon::now()->subMinutes($expired_minutes))
->having(DB::raw('COUNT(resellers.name)'), '>=', $expired_limit)
->select('resellers.name', DB::raw('COUNT(resellers.name) AS total_expired'), DB::raw('TRUNCATE(SUM(merchant_deposits.amount), 2) AS total_amount'), 'merchant_deposits.currency')
->groupBy('resellers.name', 'merchant_deposits.currency')
->get();
if (!empty($o->toArray()) && $k > 0) {
$reports[$currency] = [];
foreach ($o as $k => $v) {
$reports[$currency][$v->name] = $v->total_expired;
$reports[$currency]['Total Amount'] = $v->total_amount;
}
}
}
if (!empty($reports)) {
Notification::send(\App\Models\Admin::all(), new \App\Notifications\DepositExpiredReport($reports));
}
}
}
And in Model/Admin.php i've set receivesBroadcastNotificationsOn to update the channel name for the broadcast to send into pusher.
<?php
namespace App\Models;
use App\Trait\HasJWTSubject;
use App\Trait\UserLogsActivity;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Hash;
use Illuminate\Notifications\Notifiable;
use Laravel\Lumen\Auth\Authorizable;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Spatie\Permission\Traits\HasRoles;
/**
* Model of admin
* #package Models
*/
class Admin extends Model implements AuthenticatableContract, AuthorizableContract, JWTSubject
{
use Authenticatable, Authorizable, HasFactory, HasJWTSubject;
use UserLogsActivity;
use Notifiable;
use HasRoles;
protected $fillable = [
'name',
'username',
'password',
'status',
'timezone'
];
protected $hidden = [
'password',
];
protected $casts = [
'status' => 'boolean',
];
public const STATUS = [
'DISABLED' => false,
'ACTIVE' => true,
];
public function getIsSuperAdminAttribute()
{
return $this->hasRole('Super Admin');
}
public function setPasswordAttribute($value)
{
$this->attributes['password'] = Hash::needsRehash($value) ? Hash::make($value) : $value;
}
public function devices()
{
return $this->morphMany(Device::class, 'user');
}
public function receivesBroadcastNotificationsOn()
{
return 'App.Models.Admin.Notify';
}
}
When the notification is triggered from Notification::send(\App\Models\Admin::all(), new \App\Notifications\DepositExpiredReport($reports)); it will send broadcast notification multiple times to same broadcast channel as shown in the screenshot below
From Notification::send(\App\Models\Admin::all(), new \App\Notifications\DepositExpiredReport($reports)); it is fine to save the notification records for all the admin in database notification but for pusher i want the notification event to sent only once instead of sending multiple times ie 'x' number of admins.
Lets say i have 100 admin users then now pusher will send the event to same channel 100 times. So i want to minimize the pusher event to just 1 channel where all the admin users subscribed can receive the notification but it should also save the records for 100 users in the notification table of database.
I have two Notification channels
app/Channels/Reseller/Web/OneSignalWeb.php
<?php
namespace App\Channels\Reseller\Web;
use Berkayk\OneSignal\OneSignalClient;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Log;
use NotificationChannels\OneSignal\Exceptions\CouldNotSendNotification;
use NotificationChannels\OneSignal\OneSignalChannel;
class OneSignalWeb extends OneSignalChannel
{
public function __construct()
{
$client = new OneSignalClient(
env("ONESIGNAL_RESELLER_APP_ID"),
env("ONESIGNAL_RESELLER_REST_API_KEY"),
''
);
parent::__construct($client);
}
/**
* Send the given notification.
*
* #param mixed $notifiable
* #param \Illuminate\Notifications\Notification $notification
*
* #return \Psr\Http\Message\ResponseInterface
* #throws \NotificationChannels\OneSignal\Exceptions\CouldNotSendNotification
*/
public function send($notifiable, Notification $notification)
{
if (!$userIds = $notifiable->devices()->where('platform', 'web')->pluck('uuid')->toArray()) {
return;
}
/** #var ResponseInterface $response */
$response = $this->oneSignal->sendNotificationCustom(
$this->payload($notifiable, $notification, $userIds)
);
if ($response->getStatusCode() !== 200) {
throw CouldNotSendNotification::serviceRespondedWithAnError($response);
}
return $response;
}
}
app/Channels/Merchant/Web/OneSignalWeb.php
<?php
namespace App\Channels\Merchant\Web;
use Berkayk\OneSignal\OneSignalClient;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Log;
use NotificationChannels\OneSignal\Exceptions\CouldNotSendNotification;
use NotificationChannels\OneSignal\OneSignalChannel;
class OneSignalWeb extends OneSignalChannel
{
public function __construct()
{
$client = new OneSignalClient(
env("ONESIGNAL_MERCHANT_APP_ID"),
env("ONESIGNAL_MERCHANT_REST_API_KEY"),
''
);
parent::__construct($client);
}
/**
* Send the given notification.
*
* #param mixed $notifiable
* #param \Illuminate\Notifications\Notification $notification
*
* #return \Psr\Http\Message\ResponseInterface
* #throws \NotificationChannels\OneSignal\Exceptions\CouldNotSendNotification
*/
public function send($notifiable, Notification $notification)
{
if (!$userIds = $notifiable->devices()->where('platform', 'web')->pluck('uuid')->toArray()) {
return;
}
/** #var ResponseInterface $response */
$response = $this->oneSignal->sendNotificationCustom(
$this->payload($notifiable, $notification, $userIds)
);
if ($response->getStatusCode() !== 200) {
throw CouldNotSendNotification::serviceRespondedWithAnError($response);
}
return $response;
}
}
In both of these channel only the difference is that in __constructwe load different keys for both Reseller and Merchant
public function __construct()
{
$client = new OneSignalClient(
env("ONESIGNAL_RESELLER_APP_ID"),
env("ONESIGNAL_RESELLER_REST_API_KEY"),
''
);
parent::__construct($client);
}
And this is the Nofications/Base.php where i've load both ResellerWeb and MerchantWeb Notification in via methods
public function via($notifiable)
{
return [
'database',
'broadcast',
ResellerWeb::class,
MerchantWeb::class,
];
}
I want to optimize the norification where instead of loading MerchantWeb::class and ResellerWeb::cass i want to create and load a general channel lets say NotificationWeb::class and want to use it for both Reseller and Merchant. And when i use it i will need to switch the env() keys based on for which i use.
How can this be achieved
I am trying to pass a model to job class and when the model is sent to job class, it's incomplete there. What I mean is that it shows only two attributes there instead of 10. $queue_match is complete model (all attributes included, everything is fine) but when it is sent to Job class, then I only see two attributes.
PS: I have included my model at the top of Job class,
$z = dispatch(new updateMatchStatus($queue_match))->onConnection('database')->delay(now()->addMinutes('1'));
namespace App\Jobs;
use App\Http\Controllers\AdminController;
use App\Models\Match;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class updateMatchStatus implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $queue_match;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct(Match $queue_match)
{
//
$this->queue_match = $queue_match;
// dd($queue_match);
}
/**
* Execute the job.
*
* #return void
*/
public function handle(Match $queue_match)
{
$now = Carbon::now('PKT');
$now = Carbon::parse($now, 'PKT')->startOfMinute();
// registration close hack, will set Match status to F 30 mins before due time.
$now = $now->addMinutes(30);
$due_time = Carbon::parse($queue_match->due_time, 'PKT');
if ($now->greaterThan($due_time)) {
$queue_match->status = 'F';
// dd($queue_match);
$queue_match->save();
}
}
}
just two attributes in Screenshot
As requested, Here is Match Class
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Match extends Model
{
//
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'platform', 'category', 'map', 'fee', 'is_elite', 'due_time', 'status'
];
public function getPlatformAttribute($value) {
if ($value == 'M') {
return $value ."obile";
}
else {
return $value ."mulator";
}
}
// default attributes
protected $attributes= [
'status' => 'A',
'is_elite' => false
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
// hidden fields for return response
protected $hidden = [
'created_at', 'updated_at',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
];
public function registrations() {
return $this->hasMany('App\Models\Registration', 'match_id', 'id');
}
public function results() {
return $this->hasMany('App\Models\Result', 'match_id', 'id');
}
}
AND, this is how I get the $queue_match which is passed to job.
$queue_match = Match::create([
'category' => $request['category'],
'platform' => $request['platform'],
'map' => $request['map'],
'fee' => $request['fee'],
'due_time' => $request['due_time'],
]);