7

I use database notifications, in notification code I have method toDatabase:

public function toDatabase($notifiable)
    {
        $user = \App\SomeUsers::where('id', $notifiable->id)->first();
        return [
             'message' => $message,
        ];
    }

it returns data array which is being sent to database channel mentioned in via method of current notification:

public function via($notifiable)

    {
        return ['database'];
    }

Everything is as usual, BUT... The problem is I need id of notification in database here in current notification file so that I could broadcast message (from current notification file) to frontend which contains id of notificaion in db (so I could somehow identify it to mark as read). How to get it?

P.S. Moreover, database notification may be queueable, so... it seems that I can't get id... P.P.S Another words I need broadcast message which contains ["id" => "id of just added corresponding database notification"].

John Smith
  • 1,204
  • 3
  • 22
  • 42

3 Answers3

11
<?php

namespace App\Notifications;

use App\Channels\SocketChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Redis;

class MyCustomNotification extends Notification implements ShouldQueue
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */


    public function __construct($param)
    {
        $this->param = $param;
    }

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

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {

    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toDatabase($notifiable)
    {
        info("This is the current notification ID, it's generated right here before inserting to database");
        info($this->id);
        return [

            'id'     =>  **$this->id**,
            'message' => 'Notification message',

        ];
    }


} 

$this->id solves the problem.

https://laracasts.com/discuss/channels/laravel/get-database-notification-id-in-push-notification

P.S. I want to draw attention to one fact. When I posted this question, I knew about $this->id, but I couldn't make it work. The reason was: when I dive deeper to my target code from the top level I made changes to code, but they didn't apply. The reason is queues. You need to restart laravel worker to apply settings as Laravel caches logic or you need temporarily delete those: implements ShouldQueue and use Queueable.

John Smith
  • 1,204
  • 3
  • 22
  • 42
7

In order to retrieve the actual ID of the notifications table in Laravel, you need to cast the ID column to string. First, you need to create a new model called, Notification.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Notification extends Model
{
    /**
     * Cast variables to specified data types
     *
     * @var array
     */
    protected $casts = [
        'data' => 'array',
        'id' => 'string'
    ];
}

This way, if you retrieve the model, it will give you the actual ID of the table.

 {
        "id": "212829d6-5579-449f-a8e5-e86f0a08e0f9",
        "type": "App\\Notifications\\CronFailureNotification",
        ....
    }
  • You can use `Illuminate\Notifications\DatabaseNotification` it extends `Model` so there is no need to create notifications model. If you want to extend it furter, you can extend `DatabaseNotification` class to inherit all existing methods – Edmund Sulzanok Apr 22 '22 at 14:07
1

The accepted answer did not provide a solution for me in Laravel 8. To properly get the id of the notification, listen for the NotificationSent event and retrieve the id there. Example code:

EventServiceProvider.php

protected $listen = [
    NotificationSent::class => [
        DispatchBroadcastNotification::class
    ]
];

DispatchBroadcastNotification.php

<?php

namespace App\Listeners;

use App\Notifications\BroadcastNotification;
use Illuminate\Notifications\Events\NotificationSent;

class DispatchBroadcastNotification
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  NotificationSent $event
     * @return void
     */
    public function handle(NotificationSent $event)
    {
        $event->notifiable->notify(
            new BroadcastNotification($event->notification->id)
        );
    }
}

BroadcastNotification.php

<?php

namespace App\Notifications;

use App\Models\Tenant\User;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Notifications\Messages\BroadcastMessage;
use Illuminate\Notifications\Notification;

class BroadcastNotification extends Notification implements ShouldBroadcast
{
    public $notificationId;

    public function __construct($notificationId)
    {
        $this->notificationId = $notificationId;
    }

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

    public function toBroadcast(User $notifiable)
    {
        return new BroadcastMessage([
            'notificationId' => $this->notificationId
        ]);
    }
}
Inserve
  • 1,796
  • 1
  • 12
  • 14