Laravel nos permite el envío de notificaciones a usuarios a través de diferentes vías (SMS, mail, etc.). En este post, añadiremos notificaciones a nuestro proyecto, pero serán un tipo de notificaciones que se guardarán en la base de datos y se mostrarán en una pestaña en el header.
Creamos la tabla en la base de datos para las notificaciones, Laravel nos provee un comando para hacerlo:
1 |
php artisan notifications:table |
La ejecutamos:
1 |
php artisan migrate |
Creamos el archivo de la notificación:
1 |
php artisan make:notification NewCommentPost |
En este caso, será una notificación que se lanzará cuando haya un nuevo comentario en los posts y será enviada al usuario creador del post, avisándole de que un usuario ha comentado en uno de sus posts.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<?php namespace App\Notifications; use Illuminate\Notifications\Notification; use App\Post; use App\User; class NewCommentPost extends Notification { protected $comment; /** * Create a new notification instance. * * @return void */ public function __construct($comment) { $this->comment = $comment; } /** * Get the notification's delivery channels. * * @param mixed $notifiable * @return array */ public function via($notifiable) { return ['database']; } /** * Get the array representation of the notification. * * @param mixed $notifiable * @return array */ public function toDatabase($notifiable) { return [ 'comment' => $this->comment, 'post' => Post::find($this->comment->post_id), 'user' => User::find($this->comment->user_id) ]; } /** * Get the array representation of the notification. * * @param mixed $notifiable * @return array */ public function toArray($notifiable) { return [ // ]; } } |
- Post::find($this->comment->post_id) y User::find($this->comment->user_id) , también se podría poner con los métodos de la relación del modelo. Quedaría así $this->comment->post y $this->comment->user .
- En la función via indicamos el tipo, podríamos añadir más de uno.
- En la función toDatabase añadimos los datos que queremos acceder cuando mostremos la notificación, ahora veremos cómo hacerlo.
Puedes encontrar más información en la documentación.
Abrimos el CommentsController.php y modificamos la función store para que quede así:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
use App\Notifications\NewCommentPost; ... public function store(CommentRequest $request) { $post = Post::findOrFail($request->post_id); $comment = Comment::create([ 'body' => $request->body, 'user_id' => Auth::id(), 'post_id' => $post->id ]); if ($post->user_id != $comment->user_id) { $user = User::find($post->user_id); $user->notify(new NewCommentPost($comment)); } return redirect()->route('posts.show', $post->id); } |
Esa línea es la que hace que se envíe la notificación al usuario indicado.
Se podría añadir que una vez un usuario comente en un post, siempre que ese post tenga un comentario nuevo se le avise.
Ahora vamos a añadir el código para que se muestren las notificaciones del usuario logueado. Añadir este código en el header cuando el usuario está logueado:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> Notifications <span class="badge">{{count(Auth::user()->unreadNotifications)}}</span> </a> <ul class="dropdown-menu" role="menu"> <li> @foreach (Auth::user()->unreadNotifications as $notification) <a href="{{ route('posts.show', $notification->data['post']['id']) }}"><i>{{ $notification->data["user"]["name"] }}</i> has commented in <b>{{ $notification->data["post"]["title"] }}</b></a> @endforeach </li> </ul> </li> |
Y nos debería salir algo como ésto:
Fácilmente, se podría añadir con jQuery y Ajax que cuando se haga click en el botón Notifications se marquen como leídas las notificaciones de la lista.
1 2 |
$user = Auth::user(); $user->unreadNotifications->markAsRead(); |
-
Hola, aqui tengo un error de la clase App\Http\Request\CommentRequest does not exist, no se en que parte tengo que agreagar la linea, estuve revisando y la tengo en el controlador commentsController pero no se si tengo que agregarla en alguna otra seccion, he estado revisando y aun no logro resolverlo, como siempre te agradesco tu tiempo.
Hola Billy,
¿Has creado la clase CommentRequest? Se crea en este artículo: http://fullstackseries.com/laravel-5-4-17-anadir-comentarios-los-posts/
Si no la has creado por cualquier motivo (aunque yo te recomiendo que la crees), lo que puedes hacer en vez de poner CommentRequest poner Request en el método (en este caso store) y entonces podrás borrar la línea:
use App\Http\Requests\CommentRequest;
. Lo que pasa es que con Request no se comprobará que el usuario esté logueado para poder comentar y tampoco se comprobarán que los datos enviados del comentario sean correctos. Tendrás que hacer estas validaciones de otra manera (https://laravel.com/docs/5.4/validation).Un saludo!
Hola, si he creado la clase commentRequest, he revisado todos los pasos y todo esta correcto y me sigue saliendo el mismo error, ademas me he fijado que sale otro error es este: Whoops, looks like something went wrong.
(1/1) FatalErrorException
Trait ‘App\Http\Request\CommentRequest’ not found
in Comment.php (line 13)
He revisado todas las partes del codigo y estan bien.
He hecho toda la seccion de nuevo y el erro ha desaparecido, asiq ue algun paso debi haber hecho mal, pero ahora me salio este error FatalErrorException
Call to a member function name() on null
in web.php (line 28)
Disculpa es este error elq eu me sale «InvalidArgumentException
Route [posts.show] not defined.
in UrlGenerator.php (line 304)»
Al parecer mi error esta en esta linea return redirect()->route(‘posts.show’, $post->id); en el controllador
Hola,
Eso es que estás llamando a una ruta por el nombre posts.show y no existe. La tienes que definir en el routes.php. Debería ser algo así
Route::get('/post/{id}', 'PostsController@show')->name('posts.show');
Fíjate en el name. Mira aquí: https://laravel.com/docs/5.4/routing#named-routes
Un saludo!
muy bueno esto amigo, explicas muy bien, yo quiero algo parecido, pero en mi caso quiero que si otro usuario comenta notificarle a ese usuario si alguien comento en el mismo post, pero el problema es que no se como hacer que los usuarios que no hallan comentado en dicho post no reciban notificaciones, a demas de que tambien tendria que darle al usuario al que se le esta notificando la opcion de desactivar las notificaciones para ese post en especifico, no se si se pueda hacer algo asi
Hola Ramón,
Muchas gracias por tu comentario.
Échale un ojo a la documentación de Laravel sobre las notificaciones. Posiblemente encuentres algo que te ayude.
Saludos!