Notifications and Conclusion 🎉
Tags: tutorial, programming, laravel, beginners
Published: 2023-12-28 00:41:42

##Now, back to notifications
Now let's add a space in the navigation bar to display our notifications.

In resources/views/layouts/app.blade.php add the code below so we can use the material icons:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uxpzkqhdxqsbo9ljeh1v.png)
``` php
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
```
Let's create the "notifications" component:
`php artisan make:livewire components.notification`

In resources/views/livewire/layout/navigation.blade.php add:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6pduwj5qo1q2g6958j0.png)
``` php
@livewire('components.notification')
```

Mobile:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pw24byciovr1kpnonpdo.png)
``` php
@livewire('components.notification')
```

Let's incorporate Laravel Echo to monitor notification events. This way, as soon as a notification is received, we can dynamically reload the notifications and post listing components.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/56xrv5io4zlhghhbib4l.png)

``` php
<script>
    document.addEventListener('DOMContentLoaded', () => {
        Echo.private('App.Models.User.{{auth()->user()->id}}')
            .notification(() => {
                Livewire.dispatch('refreshNotification');
                Livewire.dispatch('refreshPostList');
            });
    });
</script>
```

In resources/views/livewire/components/notification.blade.php:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62rfbdqg29487vmkmwvx.png)

``` php
<div>
    <x-dropdown align="right" width="48">
        <x-slot name="trigger">
            <button
                class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-none transition ease-in-out duration-150">
                <span class="rounded-full p-1 bg-red-500 text-white">17</span>
                <span class="material-symbols-outlined">
                    notifications
                </span>
            </button>
        </x-slot>
        <x-slot name="content">
            <div class="p-3 text-center">
                <p>some notifications</p>
            </div>
        </x-slot>
    </x-dropdown>
</div>
```

##Notification Class
As we are going to send our notifications via the database channel, we need to create the notifications table:
`php artisan notifications:table`
`php artisan migrate`

Now let's create a notification class:
`php artisan make:notification PostCreated`

A new directory containing our class will be created:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ylbcksbp1e99iy5vlqlw.png)

In app/Notifications/PostCreated.php we will add the broadcast settings:
**The constructor:**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpw7spyzqy3jt9bwh040.png)

``` php
    public $userId;
    public $dataNotify;

    /**
     * Create a new notification instance.
     */
    public function __construct($userId, $dataNotify)
    {
        $this->userId = $userId;
        $this->dataNotify = $dataNotify;
    }
```

**Channel and type:**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xlvx2j6p2fbk77tcy71l.png)

``` php
    /**
     * Get the notification's delivery channels.
     *
     * @return array<int, string>
     */
    public function via(object $notifiable): array
    {
        return ['broadcast', 'database'];
    }

    public function broadcastType()
    {
        return 'broadcast.message';
    }
```

**Channel name and connection:**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6sk6nucjj402149dn3d.png)

``` php
    public function toBroadcast(object $notifiable): BroadcastMessage
    {
        return (new BroadcastMessage($this->dataNotify))->onConnection('database');
    }

    public function broadcastOn(): Channel
    {
        return new PrivateChannel("App.Models.User.{$this->userId}");
    }
```

To send notifications, we will choose to use the Notifiable trait, which is already incorporated into our User model by default. This gives us an efficient, out-of-the-box approach. For more information about how to use this trait: [https://laravel.com/docs/10.x/notifications#using-the-notifiable-trait](https://laravel.com/docs/10.x/notifications#using-the-notifiable-trait)

In app/Livewire/Posts/PostCreate.php we will add the action of notifying users anytime they have been tagged:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mqu898onu12s2cm2egh2.png)

``` php
if ($this->state['tagged_user_id']) {
    $taggedUser = User::query()->find($this->state['tagged_user_id']);
    $taggedUser?->notify(new PostCreated($taggedUser['id'], $this->state));
}
```

The documentation explains the correct way to retrieve user notifications [https://laravel.com/docs/10.x/notifications#accessing-the-notifications](https://laravel.com/docs/10.x/notifications#accessing-the-notifications).

Let's add notification retrieval logic to app/Livewire/Components/Notification.php:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k9h7zy3oin8pdeqc0zku.png)

``` php
    protected $listeners = [
        'refreshNotification' => '$refresh'
    ];

    public $notifications;
    public $notificationsCounter;

    public function getNotifications()
    {
        $this->notifications = auth()->user()->unreadNotifications;
        $this->notificationsCounter = $this->notifications->count();

    }

    public function render()
    {
        $this->getNotifications();

        return view('livewire.components.notification');
    }
```

And let's modify the blade to display the notification counter:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/475f5s7f80jiwj3smr2w.png)

``` php
<div>
    <x-dropdown align="right" width="48">
        <x-slot name="trigger">
            <button
                class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-none transition ease-in-out duration-150">
                @if($notificationsCounter)
                    <span class="rounded-full p-1 bg-red-500 text-white">{{$notificationsCounter}}</span>
                @endif
                <span class="material-symbols-outlined">
                    notifications
                </span>
            </button>
        </x-slot>
        <x-slot name="content">
            @foreach($notifications as $notification)
                <div class="p-3 text-center">
                    <p>You have been tagged in a new post!</p>
                </div>
            @endforeach
        </x-slot>
    </x-dropdown>
</div>
```
Let's start our worker:
`php artisan queue:work`

At this moment, our notifications are already being processed in queues and being directed in real time to marked users, as follows:
{% embed https://youtu.be/HCALH6pAzLk %}

##Conclusion
We were able to build, step by step, the real-time notification functionality using Laravel and Livewire, following only the official documentation. Despite the success, there are still several possible features to improve the project, such as:
- Creation of the validation layer.
- Creation of the repository layer.
- Pass data to the notification, such as the name of the person who tagged the user.
- Mark notifications as read.

**I'm leaving the repository link for anyone interested: [https://github.com/northoniserhardt/still-loving-docs](https://github.com/northoniserhardt/still-loving-docs)**

Beyond this, you are the one who decides! Thank you very much for following the tutorial.