Search code examples
phplaravelvue.jspusherlaravel-echo

Invalid key in subscription auth data , type : websocketError


I am using Laravel 5.8.*, laravel echo, pusher and vuejs for a private chat.

Trying to listen the broadcast-ed event using vuejs as frontend but no data received in callback from pusher. I can see the private channel and data sent to pusher but received empty. I see below messages in console when I connected to pusher :

Pusher : Event sent : {"event":"pusher:subscribe","data":{"auth":"460f6d3e4959b66a186a:3a759e55e46fc62d0188461344828ee4266edba8f1c0f5a5fd9743beb086d8cf","channel":"private-messages.1"}}

Pusher : Event recd : {"event":"pusher:error","data":{"code":null,"message":"Invalid key in subscription auth data: '460f6d3e4959b66a186a'"}}

Pusher : Error : {"type":"WebSocketError","error":{"type":"PusherError","data":{"code":null,"message":"Invalid key in subscription auth data: '460f6d3e4959b66a186a'"}}}

I tried all the ways I can but unable to find the reason for this subscription error. I had set all the pusher data (channel name, key, secret id, app id, cluster) correctly. I read all the other questions which already mentioned the same issue here in stackoverflow but none of them has relevant solution or answer. So again came here for some help if anyone connect remotely and check on my laptop.

ChatApp.vue

<template>
    <div class="chat-app">
        <Conversation :contact="selectedContact" :messages="messages" @new="saveNewMessage"/>
        <ContactsList :contacts="contacts" @selected="startConversationWith"/>
    </div>
</template>

<script>
import Conversation from './Conversation';
import ContactsList from './ContactsList';

export default {
    props: {
        user: {
            type: Object,
            required: true
        }
    },
    data(){
        return {
            selectedContact: null,
            messages: [],
            contacts: []
        };
    },
    mounted() {
        Echo.private(`messages.${this.user.id}`)
        .listen('NewMessage', (e) => {
            console.log('listening NewMessage');
            this.handleIncoming(e.message);
        });
        axios.get('/contacts')
        .then((response)=>{
            this.contacts = response.data;
        });
    },
    methods:{
        startConversationWith(contact){
            this.updateUnreadCount(contact, true);
            axios.get(`/conversation/${contact.id}`)
            .then((response) => {
                this.messages = response.data;
                this.selectedContact = contact;
            })
        },
        saveNewMessage(message){
            this.messages.push(message);
        },
        handleIncoming(message){
            if (this.selectedContact && message.from == this.selectedContact.id) {
                this.saveNewMessage(message);
                return;
            }
            this.updateUnreadCount(message.from_contact, false);
        },
        updateUnreadCount(contact, reset){
            this.contacts = this.contacts.map((single)=>{
                if (single.id !== contact.id) {
                    return single;
                }
                if (reset)
                    single.unread = 0;
                else
                    single.unread += 1;
                return single;
            })
        }
    },
    components: {Conversation, ContactsList}
}
</script>

<style lang="scss" scoped>
.chat-app{
    display:flex;
}
</style>

EVENT

<?php

namespace App\Events;

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 App\Message;

class NewMessage implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

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

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('messages.'.$this->message->to);
    }

    public function broadcastWith(){
        $this->message->load('fromContact');
        return ["message" => $this->message];
    }
}

channels.php

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

broadcasting.php

'pusher' => [
            'driver' => 'pusher',
            'key' => env('PUSHER_APP_KEY'),
            'secret' => env('PUSHER_APP_SECRET'),
            'app_id' => env('PUSHER_APP_ID'),
            'options' => [
                'cluster' => env('PUSHER_APP_CLUSTER'),
                'encrypted' => true,
            ],
        ],

connection with laravel echo

 window.Echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.MIX_PUSHER_APP_KEY,
    cluster: process.env.MIX_PUSHER_APP_CLUSTER,
    encrypted: true
});

.env

PUSHER_APP_ID=xxxx
PUSHER_APP_KEY=dbxxxxxxxb29
PUSHER_APP_SECRET=160xxxxxxxx11af
PUSHER_APP_CLUSTER=ap2

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

BROADCAST_DRIVER=pusher
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

pusher error

event detected by pusher

There are no errors in the error log of pusher dashboard.


Solution

  • The public key in your client JS is different from the one you have set in your .env file.

    I can see from the screenshot from the client that the public key begins c07d341 wheres in your 'env file this is set as:

    PUSHER_APP_SECRET=160xxxxxxxx11af

    Finally the error message you are getting relates to a public key mismatch.

    Have you possibly updated your keys without re-compiling your Javascript dependencies using the command

    npm run dev
    

    If that doesn't solve the issue, you may also want to check you have not hardcoded the incorrect public key in another location