I have the same problem and cant for the life of me understand what I'm doing wrong. Except for how im setting up window.echo my code is the same as yours.
Nov 25, 2024
3
Level 1
Reverb: Error joining private channel
I have a project in react native and laravel, I'm using laravel reverb to make a chat, but I'm facing some problems in the channel authentication. This is the error:
Laravel: v11.31.0 PHP: v8.2.0 Reverb: v1.0
(NOBRIDGE) LOG Pusher : : ["Event sent",{"event":"pusher:subscribe","data":{"channel":"private-users.1"}}]
(NOBRIDGE) LOG Pusher : : ["Event recd",{"event":"pusher:error","data":{"code":4009,"message":"Connection is unauthorized"}}]
(NOBRIDGE) WARN Pusher : : [{"type":"PusherError","data":{"code":4009,"message":"Connection is unauthorized"}}]
(NOBRIDGE) LOG Pusher connection error: {"data": {"code": 4009, "message": "Connection is unauthorized"}, "type": "PusherError"}
.env backend
REVERB_APP_ID=129771
REVERB_APP_KEY=pm4tekz01ihxkkyeuuev
REVERB_APP_SECRET=tl5uula15etq5qaviylb
REVERB_HOST="10.20.30.98"
REVERB_PORT=8080
REVERB_SCHEME=http
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"
.env frontend
REVERB_APP_ID=129771
REVERB_APP_KEY=pm4tekz01ihxkkyeuuev
REVERB_APP_SECRET=tl5uula15etq5qaviylb
REVERB_HOST="10.20.30.98"
REVERB_PORT=8080
REVERB_SCHEME=http
##Backend
resources/js/echo.js
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
Providers/BroadcastServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\ServiceProvider;
class BroadcastServiceProvider extends ServiceProvider {
/**
* Bootstrap any application services.
*/
public function boot(): void {
Broadcast::routes([
'prefix' => 'api/v1',
'middleware' => ['api', 'auth:sanctum'],
]);
require base_path('routes/channels.php');
}
}
Events/MessageSent.php
<?php
namespace App\Events;
use App\Models\User;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class MessageSent implements ShouldBroadcastNow {
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*/
public $receiver;
public $sender;
public $message;
public function __construct($receiver, $sender, $message) {
$this->receiver = [
'id' => $receiver->id,
'name' => $receiver->name,
];
$this->sender = [
'id' => $sender->id,
'name' => $sender->name,
];
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*/
public function broadcastOn(): Channel {
return new PrivateChannel('users.' . $this->receiver['id']);
}
}
routes/channels.php
Broadcast::channel('users.{id}', function ($user, $id) {
return (int)$user->id === (int)$id;
});
##Frontend Echo Instance
import {useEffect, useState} from "react";
import {apiX} from "@/lib/axios";
import Echo from "laravel-echo";
import Pusher from "pusher-js/react-native";
// @ts-ignore
import {REVERB_APP_KEY, REVERB_HOST, REVERB_PORT, REVERB_SCHEME, EXPO_PUBLIC_API_URL} from "@env";
const useEcho = () => {
const [echoInstance, setEchoInstance] = useState(null);
useEffect(() => {
// Setup Pusher client
const PusherClient = new Pusher(REVERB_APP_KEY, {
wsHost: REVERB_HOST,
wsPort: REVERB_PORT ?? 80,
wssPort: REVERB_PORT ?? 443,
forceTLS: (REVERB_SCHEME ?? "https") === "https",
enabledTransports: ["ws", "wss"],
disableStats: true,
cluster: "mt1",
authorizer: (channel, options) => {
return {
authorize: (socketId, callback) => {
apiX
.post("broadcasting/auth", {
socket_id: socketId,
channel_name: channel.name,
})
.then((response) => {
callback(false, response.data);
})
.catch((error) => {
callback(true, error);
});
},
};
},
});
// Create Echo instance
const echo = new Echo({
broadcaster: "reverb",
client: PusherClient,
});
Pusher.logToConsole = true;
setEchoInstance(echo);
// Cleanup on unmount
return () => {
if (echo) {
echo.disconnect();
}
};
}, []);
return echoInstance;
};
export default useEcho;
Subscribe to chanel
function subscribeToChatChannel(): void {
if (echo) {
console.log('subscribeToChatChannel');
// @ts-ignore
echo.private(`users.${sessionUserId}`).listen("MessageSent", (e: any) => {
console.log("Real time recive", e);
setMessages((prevMessages): Message[] => [
...prevMessages,
{
id: e.message?.id,
message: e.message?.message,
from: e.message?.from,
created_at: e.message?.created_at,
},
]);
});
}
}
useEffect(() => {
if (scrollViewRef.current) {
scrollViewRef.current.scrollToEnd({animated: true});
}
}, [messages]);
useEffect(() => {
if (echo) {
subscribeToChatChannel();
}
return () => {
if (echo && id) {
console.log("leaveChannel");
// @ts-ignore
echo.leaveChannel(`chat`);
}
};
}, [echo, session]);
The connection with the pusher seems to be working but the authentication with the channel is not, can anyone help?
Please or to participate in this conversation.