I am using Laravel 11 With Laravel Reverb and Laravel Livewire. When I send Message to user It not display Realtime to another user. When I change User and Open again then Display Messages. I need your help and support.
User.php
<?php
namespace AppModels;
// use IlluminateContractsAuthMustVerifyEmail;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
'avatar',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
public function sendMessages()
{
return $this->hasMany(Message::class,'sender_id');
}
public function receievedMessage()
{
return $this->hasMany(Message::class,'receiver_id');
}
}
Message.php
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentBuilder;
class Message extends Model
{
use HasFactory;
protected $fillable = [
'message',
'sender_id',
'receiver_id',
];
public function sender()
{
return $this->belongsTo(User::class,'sender_id');
}
public function receiver()
{
return $this->belongsTo(User::class,'receiver_id');
}
public static function readMessages($senderId, ?int $receiverId)
{
Message::query()->where('sender_id', $senderId)->where('receiver_id', $receiverId )->update(['is_read'=>true]);
}
public function scopeMessageList($query, $selectedUser)
{
return $query->where(function(Builder $query) use($selectedUser){
$query->where('sender_id',auth()->id())
->where('receiver_id',$selectedUser);
})->orWhere(function(Builder $query) use($selectedUser){
$query->where('sender_id',$selectedUser)
->where('receiver_id',auth()->id());
});
}
}
web.php
Route::middleware('auth')->group(function(){
Route::view('/','chat');
});
Livewire/chat.php
<?php
namespace AppLivewire;
use LivewireComponent;
use AppModelsUser;
use AppModelsMessage;
use LivewireAttributesOn;
use IlluminateSupportFacadesAuth;
use AppEventsMessageEvent;
class chat extends Component
{
public $messages = [];
public $text;
public $users;
public $selectedUser;
public $newMessage = false;
public $userWithNewMessage = [];
public $conversation = [];
protected $listeners = [
'showMessages' => 'showMessages',
];
public function showMessages($userId)
{
$this->selectedUser = User::find($userId);
$this->messages = Message::messageList($userId)->get()->toArray();
}
#[On('echo:livewire_chatapp,MessageEvent')]
public function listenForMessage($data)
{
$this->messages[] = $data['message'];
}
public function updatedMessages()
{
$this->dispatchBrowserEvent('scrollToBottom');
}
public function sendMessage()
{
$user = Auth::user();
// Create a new Message instance and save it
$message = new Message();
MessageEvent::dispatch($this->text, $user->id, $this->selectedUser['id']);
$this->text = null;
}
public function render()
{
$this->users = User::where('id','<>',auth()->id())->get();
return view('livewire.chat');
}
}
livewire/chat.blade.php
<div>
<div class="col-9">
<h3 class="card-header">{{ __('USERS') }}</h3>
<hr />
<div class="col-12 row">
<div class = "col-md-4">
<ul class="list-group">
@foreach($users as $user)
<li wire:click="showMessages({{ $user->id }})"
class="list-group-item d-flex align-items-center {{(optional($selectedUser)['id']) == $user->id ? 'active' : ''}}">
@if(!empty($user->avatar))
<img src="{{ asset('avatars/' . $user->avatar) }}" alt="User Avatar" class="avatar rounded-circle d-flex align-self-center z-depth-1" style="width:50px;height:50px;margin-right:25px;">
@else
<img src="{{ asset('avatars/default_user.png' ) }}" alt="User Avatar" class="avatar rounded-circle d-flex align-self-center z-depth-1" style="width:50px;height:50px;margin-right:25px;">
@endif
{{$user->name}}
</li>
@endforeach
</ul>
</div>
<div class = "col-md-8">
@if($selectedUser)
<section class = "">
<div class="container">
<div class="row d-flex justify-content-center">
<div class="col-md-12 col-lg-12 col-xl-12">
<div class="card" id="card1" style="">
<div class="card-header d-flex align-items-center p-3" style="font-size:large;">
<i class="fas fa-angle-left"></i>
@if(!empty($selectedUser['avatar']))
<img src="{{ asset('avatars/' . $selectedUser['avatar']) }}" alt="User Avatar" class="avatar rounded-circle d-flex align-self-center z-depth-1" style="width:50px;height:50px;margin-right:25px;">
@else
<img src="{{ asset('avatars/default_user.png' ) }}" alt="User Avatar" class="avatar rounded-circle d-flex align-self-center z-depth-1" style="width:50px;height:50px;margin-right:25px;">
@endif
<p class="mb-0 fw-bold">{{$selectedUser['name']}}</p>
<i class="fas fa-times"></i>
</div>
<div class="card-body">
<div class="message-body" style="height:500px;overflow: auto;flex-direction: column-reverse;">
@foreach($messages as $message)
@if($message['receiver_id'] == auth()->id())
<div class="d-flex flex-row justify-content-start mb-4">
{{-- <img src="https://mdbootstrap.com/img/Photos/Avatars/avatar-8.webp" alt="avatar" class="avatar rounded-circle d-flex align-self-center mr-2 z-depth-1" style="width:50px;height:50px;"> --}}
<div class="p-3 ms-3" style="border-radius:15px;background-color:rgba(57,192,237,.2);height:fit-content;">
<p class="small mb-0">{{$message['message']}}</p>
</div>
</div>
@else
<div class="d-flex flex-row justify-content-end mb-4">
<div class="p-3 me-3 border" style="border-radius:15px;background-color:#fbfbfb;height:fit-content;">
<p class="small mb-0">{{$message['message']}}</p>
</div>
{{-- <img src="https://mdbootstrap.com/img/Photos/Avatars/avatar-4.webp" alt="avatar" class="avatar rounded-circle d-flex align-self-center mr-2 z-depth-1" style="width:50px;height:50px;"> --}}
</div>
@endif
@endforeach
</div>
<div class=" row form-outline">
<input class="form-control" id="textAreaExample" wire:model.debounce.100ms="text" placeholder="Type your Message...">
<button wire:click="sendMessage" class="btn btn-primary mt-2"> send</button>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
@endif
</div>
</div>
</div>
</div>
MessageEvent.php
<?php
namespace AppEvents;
use AppModelsMessage;
use IlluminateBroadcastingChannel;
use IlluminateBroadcastingInteractsWithSockets;
use IlluminateBroadcastingPresenceChannel;
use IlluminateBroadcastingPrivateChannel;
use IlluminateContractsBroadcastingShouldBroadcast;
use IlluminateFoundationEventsDispatchable;
use IlluminateQueueSerializesModels;
class MessageEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*/
public string $message;
public $sender_id, $receiver_id;
public function __construct($content, $sender_id, $receiver_id)
{
$this->message = $content; // Initialize the $message property
$this->receiver_id = $receiver_id;
$this->sender_id = $sender_id;
// Save the message to the database or perform any other necessary operations
$message = new Message();
$message->message = $content;
$message->receiver_id = $receiver_id;
$message->sender_id = $sender_id;
$message->save();
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, IlluminateBroadcastingChannel>
*/
public function broadcastOn()
{
return new PrivateChannel('livewire_chatapp');
}
}