I have a filament (laravel) project. I’m using filament for whole application. Authentication, roles, permissions everything is handled through filament.
In a filament custom page, I need to use Laravel reverb for real time updates without reloading page.
For it’s setup, I followed the official docs of laravel reverb.
But on client side, I have not used the echo.js generated by php artisan install:broadcasting
, instead used
config/filament.php
:
...
'broadcasting' => [
'echo' => [
'broadcaster' => 'reverb',
'key' => env('VITE_REVERB_APP_KEY'),
'cluster' => env('VITE_REVERB_APP_CLUSTER'),
'wsHost' => env('VITE_REVERB_HOST'),
'wsPort' => env('VITE_REVERB_PORT', 80),
'wssPort' => env('VITE_REVERB_PORT', 443),
'authEndpoint' => '/broadcasting/auth',
'disableStats' => true,
'encrypted' => true,
'forceTLS' => env('VITE_REVERB_SCHEME', 'https') === 'https',
],
],
...
Also added Broadcast::routes(['middleware' => [FilamentHttpMiddlewareAuthenticate::class]]);
to boot
method of AppServiceProvider.php
, because without this I was getting 404 not found
error on '/broadcasting/auth'
.
Now public channels are working without any issue but private channels are not working.
Below is the code of Event NewGroupMessage.php
<?php
namespace AppEvents;
use AppModelsGroupMessage;
use IlluminateBroadcastingChannel;
use IlluminateBroadcastingInteractsWithSockets;
use IlluminateBroadcastingPresenceChannel;
use IlluminateBroadcastingPrivateChannel;
use IlluminateContractsBroadcastingShouldBroadcast;
use IlluminateFoundationEventsDispatchable;
use IlluminateQueueSerializesModels;
class NewGroupMessage implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*/
public function __construct(public GroupMessage $message)
{
//
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, IlluminateBroadcastingChannel>
*/
public function broadcastOn(): array
{
return [
new PrivateChannel('new-group-message.' . $this->message->group_id),
new Channel('new-group-message'),
];
}
public function broadcastWith()
{
return [
'id' => $this->message->id,
'created_by_id' => $this->message->created_by_id,
'message' => $this->message->message,
'created_at' => $this->message->created_at,
];
}
}
channels.php
<?php
use IlluminateSupportFacadesBroadcast;
Broadcast::channel('App.Models.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Broadcast::channel('new-group-message.{groupId}', function ($user, $groupId) {
return true;
});
In blade file:
<script>
function getMessages() {
window.Echo.private('new-group-message.{{ $groupId }}')
.listen('NewGroupMessage', (e) => {
console.log('new group message private ');
console.log(e);
})
window.Echo.channel('new-group-message')
.listen('NewGroupMessage', (e) => {
console.log('new group message public ');
console.log(e);
})
}
window.addEventListener('load', getMessages);
</script>
Here public channel works fine but private channel doesn’t even subscribe to channel.
Please help, what I’m missing?
I’m using:
Laravel: 11.18.1
Filament: 3.2
Reverb: 1.0
Laravel Echo: 1.16.1
After trying so many things and reading official docs of Laravel Broadcasting, Laravel Reverb, and Filament, it is now working. Sharing the solution below for other developers facing similar issue:
Either add following lines of code to boot
method of
AppServiceProvider.php:
// other code if any
IlluminateSupportFacadesBroadcast::routes([
'middleware' => [
IlluminateCookieMiddlewareEncryptCookies::class,
IlluminateSessionMiddlewareStartSession::class,
IlluminateSessionMiddlewareAuthenticateSession::class,
IlluminateFoundationHttpMiddlewareVerifyCsrfToken::class,
FilamentHttpMiddlewareAuthenticate::class,
]
]);
require base_path('routes/channels.php');
Or add following lines of code to bootstrap/app.php:
->withBroadcasting(
__DIR__ . '/../routes/channels.php',
[
'middleware' => [
IlluminateCookieMiddlewareEncryptCookies::class,
IlluminateSessionMiddlewareStartSession::class,
IlluminateSessionMiddlewareAuthenticateSession::class,
IlluminateFoundationHttpMiddlewareVerifyCsrfToken::class,
FilamentHttpMiddlewareAuthenticate::class,
]
],
)
Final bootstrapapp.php
will look like this:
<?php
use IlluminateFoundationApplication;
use IlluminateFoundationConfigurationExceptions;
use IlluminateFoundationConfigurationMiddleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withBroadcasting(
__DIR__ . '/../routes/channels.php',
[
'middleware' => [
IlluminateCookieMiddlewareEncryptCookies::class,
IlluminateSessionMiddlewareStartSession::class,
IlluminateSessionMiddlewareAuthenticateSession::class,
IlluminateFoundationHttpMiddlewareVerifyCsrfToken::class,
FilamentHttpMiddlewareAuthenticate::class,
]
],
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
NOTE: Add above code in one file only. Either in AppServiceProvider
or bootstrapapp.php
.