Search code examples
redisnotificationslaravel-5.4broadcastinglaravel-echo

Laravel 5.4 : Listening For Notifications doesn't work with me


I can't get this code works following (laravel5.4/notifications#broadcast-notifications):

Echo.private('App.User.' + userId)
    .notification((notification) => {
        console.log(notification.type);
    });

Here my code :
app.js :

require('./bootstrap')

import Echo from 'laravel-echo'

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: 'http://127.0.0.1:6001'
})


window.Echo.private('App.User.' + window.Laravel.user.id)               
.notification((notification) => {
    console.log(notification);
    // toastr.info(' has created new ticket !! ', 'info');        
});

CreateTeckitNotify:

<?php

namespace App\Notifications\Ticket;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\BroadcastMessage;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;

use App\Models\Ticket\Ticket;



class CreateTicketNotify extends Notification  implements ShouldQueue, ShouldBroadcast
{
    use Queueable, SerializesModels;


    public $ticket;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($ticket)
    {
        $this->ticket = $ticket;
    }

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

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        $url = url('/ticket/'.$this->ticket->id);
        return (new MailMessage)
                    ->subject('New Ticket Created')
                    ->greeting('Hello, '.$this->ticket->user->lastname.' !')
                    ->line('A new ticket has been created')
                    ->action('View Ticket', $url)
                    ->line('Thank you for using our application!');
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
       return [
            'ticket_id' => $this->ticket->id,                     
        ];
    }

    // public function toDatabase($notifiable)
    // {
    //     return [

    //     ];
    // }

    public function toBroadcast($notifiable)
    {

        return new BroadcastMessage([
            'ticket' => $this->ticket
        ]);
    }


}

Route :

Route::get('/test', function() {    
    $user = \App\User::find(2);

    $user->notify(new \App\Notifications\Ticket\CreateTicketNotify('Hello There'));
    return "Event has been sent!";
});

Channels Routes :

Broadcast::channel('App.User.{id}', function ($user, $id) {
    return (int) $user->id === (int) $id;
});

Broadcast::channel('ticket.{id}', function ($user, $id) {
    // $ticket = App\Models\Ticket\Ticket::find($ticketID);
    // return $ticket->category->users->has(Auth::id());
    // if(Auth::id()==1)        
    // if($id == 0)
    //  return false;
    // else
        return true;
    $ticket = App\Models\Ticket\Ticket::find($id);

    if (in_array(Auth::id(), $ticket->category->users->pluck('id')->toArray()) )
        return true;
    else
        return false;

    // return (int) $user->id !== (int) App\Models\Ticket\Ticket::find($ticketID)->user->id;
    // else
    //  return false;
});

User Model :

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
use Spatie\MediaLibrary\HasMedia\Interfaces\HasMedia;
use Auth;

class User extends Authenticatable implements HasMedia
{
    use Notifiable, HasRoles, HasMediaTrait;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'lastname', 'firstname', 'email', 'password', 'active',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];




    public function tickets()
    {
        return $this->hasMany('App\Models\Ticket\Ticket');
    } 

    public function receivesBroadcastNotificationsOn()
    {
        return 'users.'.$this->id;
    }
}

CreateTicketEvent

<?php

namespace App\Events;

use App\Events\Event;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Queue\ShouldQueue;


use App\Models\Ticket\Ticket;

class CreateTicketEvent implements ShouldQueue, ShouldBroadcast 
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $ticket;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Ticket $ticket)
    {
        $this->ticket = $ticket;
        //  $this->ticket = array(
        //     'power'=> '10'
        // );
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {        
        return new PrivateChannel('ticket.' . $this->ticket->id);
        // return ['ticket'];
    }

    // public function broadcastWith()
    // {
    //     return array('subject' => $this->ticket->subject);
    // }
}

My Terminals : enter image description here Console output :

[03:31:28] - 8bnJMpO-fFVs9LSyAAAE joined channel: ticket
[03:31:28] - 8bnJMpO-fFVs9LSyAAAE authenticated for: private-App.User.2
[03:31:28] - 8bnJMpO-fFVs9LSyAAAE joined channel: private-App.User.2
Channel: private-users.2
Event: Illuminate\Notifications\Events\BroadcastNotificationCreated
CHANNEL private-users.2

As you can see the user 2 has joined the channel and the notification has been fired but no thing is shown using this :

window.Echo.private('App.User.' + window.Laravel.user.id)               
    .notification((notification) => {
        console.log(notification);
        // toastr.info(' has created new ticket !! ', 'info');        
    });

Please Help me ....


Solution

  • I think it is because you have customized the Notification channel using receivesBroadcastNotificationsOn() in User model and you are listening event on App.User.* not on user.*

    So just remove receivesBroadcastNotificationsOn() from the User model and check again.

    Hope this helps