Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

karu's avatar
Level 1

Laravel Sanctum API, Vue 3 frontend. Reverb won't work.

No idea why it wont live update. Just one error and not much to work with

event: "pusher:error", data: "{"code":4001,"message":"Application does not exist"}"}
data
: 
"{\"code\":4001,\"message\":\"Application does not exist\"}"
event
: 
"pusher:error"

Backend

event

public function __construct(public Message $message) {
        //
    }

    public function broadcastOn(): array {
        return [
            new PrivateChannel('App.Models.User.'.$this->message->user_id),
        ];
    }

job

 public function __construct(private Message $message) {
        //
    }

    public function handle(): void {
        GotMessage::dispatch($this->message);
    }

i started job with php artisan queue:listen

2024-04-27 13:31:17 App\Jobs\SendMessage .............................................................. 41.93ms DONE
  2024-04-27 13:31:18 App\Events\GotMessage .................................................................. RUNNING
  2024-04-27 13:31:18 App\Events\GotMessage ............................................................ 275.98ms DONE
  2024-04-27 13:35:32 App\Jobs\SendMessage ................................................................... RUNNING
  2024-04-27 13:35:32 App\Jobs\SendMessage .............................................................. 35.65ms DONE
  2024-04-27 13:35:33 App\Events\GotMessage .................................................................. RUNNING
  2024-04-27 13:35:33 App\Events\GotMessage ............................................................ 244.86ms DONE

seems fine when i send message.

channels

use Illuminate\Support\Facades\Broadcast;

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

messages got injected fine to the database with the right values and so on

Frontend main.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,
  wssPort: import.meta.env.VITE_REVERB_PORT,
  forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
  enabledTransports: ['ws', 'wss'],
  authEndpoint: '/sanctum/csrf-cookie',
})

.env

VITE_REVERB_APP_KEY=ku6wfap6vieqppyfltz9
VITE_REVERB_HOST=localhost
VITE_REVERB_PORT=8080
VITE_REVERB_SCHEME=http

PrivateChatPage

<script setup>
import { ref, onMounted } from 'vue';
import axios from '../lib/axios';

const messages = ref([]);
const newMessage = ref('');
const token = localStorage.getItem('token');
const userId = ref('');

// Function to fetch messages
async function fetchMessages() {
    try {
        const response = await axios.get('/api/v1/messages');
        messages.value = response.data;
    } catch (error) {
        console.error('Failed to fetch messages:', error);
    }
}

onMounted(async() => {
    try {
        // Fetch user data using the token
        const userResponse = await axios.get(`/api/v1/user/${token}`);

        if (userResponse.status === 200) {

            userId.value = userResponse.data.data.id;
            //console.log('userId: ', userId.value)
        } else {
            console.log('Failed to fetch user preferences');
        }
    } catch (error) {
        console.log(error);
    }

    Echo.private(`App.Models.User.${userId.value}`)
    .listen('GotMessage', (e) => {
            messages.value.push({
                id: Date.now(),
                text: e.message.text,
                user_id: e.user.id,
                time: new Date().toLocaleTimeString()
            });
        });
    fetchMessages();
});

async function sendMessage() {
    if (newMessage.value.trim()) {
        const tempMessage = {
            id: Date.now(),
            text: newMessage.value,
            user_id: userId.value,
            time: new Date().toLocaleTimeString()
        };
        messages.value.push(tempMessage);
        newMessage.value = '';

        try {
            await axios.post('/api/v1/message', { text: tempMessage.text });
        } catch (error) {
            console.error('Failed to send message:', error);
        }
    }
}

</script>

messages comes when manually refreshing the page so api endpoints seems fine. its just the live update that wont work. No idea what is wrong. Ping pong in the localhost network together with

{type: "update",…}
type
: 
"update"
updates
: 
[{type: "js-update", timestamp: 1714224989450, path: "/src/views/PrivateChatPage.vue",…}]

comes too. the ws link comes like this

ws://localhost:8080/app/ku6wfap6vieqppyfltz9?protocol=7&client=js&version=8.4.0-rc2&flash=false

but together with the error message that doesn't say much more then it doesn't work...

0 likes
1 reply
karu's avatar
Level 1

So i narrow it down to this issue.

POST http://localhost:8000/sanctum/csrf-cookie 405 (Method Not Allowed)

no idea why it try to post or how to change it?

frontend main.js

/* Reverb setup */
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,
  wssPort: import.meta.env.VITE_REVERB_PORT,
  forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
  enabledTransports: ['ws', 'wss'],
  auth: {
    headers: {
      Authorization: "Bearer " + localStorage.getItem("token"),
    },
  },
  method: 'GET',
  authEndpoint: 'http://localhost:8000/sanctum/csrf-cookie',
});

Please or to participate in this conversation.