Echo Version: 1.8.0
Laravel Version: 7.0
PHP Version: 7.2.
NPM Version: 6.12.1
Node Version: 12.13.1
Description: I'm trying to send notifications to users,
My pusher connection is good because it sends on public channels
And also, i get this message on my console
[2020-07-24 21:08:09][355] Processed: Illuminate\Notifications\Events\BroadcastNotificationCreated
and on pusher i also see that the message was sent.
I also don't get any errors on my browser console as all the websocket connections are working well.
But i still dont get any messages.
I tried
Echo.private('App.User.' +userId)
.notification((notification) => {
console.log(notification);
});
I also tried
Echo.private('App.User.' + userId)
.listen('.Illuminate\\Notifications\\Events\\BroadcastNotificationCreated', (e) => {
console.log('Event Notification received ', e)
});
Now I turned on Pusher error logging and i got
app.js:42600 Pusher : : ["JSON returned from auth endpoint was invalid, yet status code was 200. Data was: <!DOCTYPE html>\r\n<html lang=\"en\">\r\n
I also followed many tutorials and the docs
All to no avail.
Steps To Reproduce:
Create a notification and declare both the toArray method and toBroadcast methods but echo fails to catch messages from pusher
I finally solved this issue myself
Steps
In my bootstrap.js file
window.Echo = new Echo({
broadcaster: "pusher",
key: "my key",
cluster: "eu",
encrypted: true,
authEndpoint: "api/broadcasting/auth",
auth: {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
},
});
Then in my routes/api.php file,
Route::middleware('auth:api')->post('broadcasting/auth', function (Request $request) {
$pusher = new Pusher\Pusher(
$app_key,
$app_secret,
$app_id
);
return $pusher->socket_auth($request->request->get('private-my-channel'),($request->request->get('socket_id'));
});
There is more info on this in the documentation,
I hope it helps someone someday
Related
I am building a real-time chat application with Laravel and Nuxt (Front-end and Back-end separated) using Pusher and Laravel-Echo, I have configured Laravel with pusher and it works fine and can see my requests in the Pusher debug console, I also want to mention two things first, I handle my authentication using Laravel-JWT and Nuxt-Auth and second, it works with public channels but since I converted it to private, Nuxt client can not subscribe anymore.
Here is error image:
Here is my Laravel config:
.env
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=MY_APP_ID
PUSHER_APP_KEY=MY_APP_KEY
PUSHER_APP_SECRET=MY_APP_SECRET
PUSHER_APP_CLUSTER=eu
channels.php
Broadcast::channel('chat', function() {
return true;
});
ChatController.php
public function sendMessage(Request $req) {
$user = Auth::user();
broadcast(new ChatEvent($user, $req->message))
->toOthers();
}
ChatEvent.php
public function __construct(User $user, $message)
{
$this->user = $user;
$this->message = $message;
}
public function broadcastAs()
{
return 'chat-event';
}
public function broadcastOn()
{
return new PrivateChannel('chat');
}
EventServiceProvider
use App\Events\ChatEvent;
use App\Listeners\SendMessageNotification;
...
protected $listen = [
ChatEvent::class => [
SendMessageNotification::class,
],
];
composer.json
"require": {
...
"pusher/pusher-php-server": "^7.0",
"tymon/jwt-auth": "^1.0"
}
Here is my Nuxt config:
package.json
"dependencies": {
...
"#nuxtjs/auth-next": "5.0.0-1624817847.21691f1",
"nuxt": "^2.14.6",
"pusher-js": "^7.0.3",
},
"devDependencies": {
...
"#nuxtjs/laravel-echo": "^1.1.0",
}
nuxt.config.js
buildModules: [
...
'#nuxtjs/laravel-echo',
],
echo: {
broadcaster: 'pusher',
key: 'my-app-key',
cluster: 'eu',
forceTLS: true,
plugins: ['~/plugins/echo.js']
},
echo.js plugin
export default function ({ $echo }) {
console.log($echo)
}
chat page index.vue
mounted() {
this.$echo.private(`chat`)
.listen(`chat-event`, (e) => {
this.addNewMessage(e.user, e.message)
})
.listenForWhisper('typing', (e) => {
console.log(e.name);
})
},
watch: {
typeMessage() {
this.$echo.private(`chat`)
.whisper('typing', {
name: this.typeMessage
})
}
},
Here is my echo console log:
My attempts to fix the error
I tried to test the back-end with the postman, and the pusher debug console works fine:
I tried to change the channel to public, and it works fine.
Conclusion
I think the problem comes from the authentication part when trying to subscribe to a private channel, hope anyone can help!
You are clearly facing a connection issue between your client and your API because of authentication.
Try with basic config without forceTLS (it must be also disabled in pusher website under App settings section).
In addition, be sure that your echo instance is hitting your auth endpoint with the required headers. It's needed for private/presence channels.
In my case I'm using passport so auth must be done with Bearer token attached in the header.
broadcaster: 'pusher',
key: process.env.VUE_APP_PUSHER_KEY,
cluster: process.env.VUE_APP_PUSHER_CLUSTER,
authEndpoint: process.env.VUE_APP_API_URL + '/broadcasting/auth',
auth: {
headers: {
Authorization: 'Bearer ' + this.$auth.token()
}
}
EDIT: sorry for not clarifying enough.
Presence/private channels are allowed only for authenticated users. Since you are using JWT you need to provide an Authorization header with the Bearer access token that you get when the user logs in.
I'm not sure how nuxt handles user tokens, but the this.$auth.token() is just a reference to how I retrieve a user's token by using websanova vue auth. But you may handle and store the token at the user's end in many ways
I have spend many hours to solve this issue of mine, reading the doc multiple times, googling here and there: SO, Laracast, Larachat, etc, but still couldn't get Laravel Echo to subscribe to Pusher presence channel, and it doesn't show any error in console tab
Public and Private channel are working fine and smooth, users can subscribe, users can listen / trigger event(s)
Note: before creation of this post, I have search questions related to my current issue, none of them have answer
Some questions similar to mine:
https://laravelquestions.com/2020/12/15/laravel-echo-not-joining-presence-channel-in-production/
Laravel Echo + Laravel Passport auth in private / presence websockets channels
https://laravel.io/forum/facing-issues-upon-subscribing-to-presence-channel
etc..
Spec:
Laravel: 7.30.1
laravel-Echo: 1.10.0 (latest; atm)
pusher/pusher-php-server: 4.0
pusher-js: 7.0.3 (latest; atm)
In resource/js/bootstrap.js
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
forceTLS: true,
authEndpoint: '/api/broadcasting/auth',
auth: {
headers: {
'Authorization': `Bearer ${localStorage['token']}`
}
}
});
In routes/api.php
// https://stackoverflow.com/questions/55555844/authorizing-broadcasting-channel-in-an-spa
Route::post('/broadcasting/auth', function (Request $request) {
$pusher = new Pusher\Pusher(
env('PUSHER_APP_KEY'),
env('PUSHER_APP_SECRET'),
env('PUSHER_APP_ID'),
[
'cluster' => env('PUSHER_APP_CLUSTER')
]
);
// This will return JSON response: {auth:"__KEY__"}, see comment below
// https://pusher.com/docs/channels/server_api/authenticating-users
$response = $pusher->socket_auth($request->request->get('channel_name'), $request->request->get('socket_id'));
return $response;
})->middleware('auth:sanctum');
In routes/channels.php
// https://laravel.com/docs/8.x/broadcasting#authorizing-presence-channels
Broadcast::channel('whatever', function ($user) {
return [
'id' => $user->id,
'name' => $user->name
];
});
In home.vue
...
...
created() {
Echo.join('whatever') // DOES NOT WORK, Even in mounted() vue lifehook, and in Pusher dashboard, it doesn't show this channel name
.here((users) => {
console.table(users)
})
}
Q: Why Laravel Echo not subscribing to Pusher presence channel? and even in Pusher, it doesn't show channel name: presence-whatever, only disconnected (after I refreshed the page) and then connected like nothing happen
Thanks in advance
1. Make sure to set the broadcast driver to .env after that do php artisan config:clear
BROADCAST_DRIVER=pusher
2. Ferify your auth.php. I have like this
3. Check your broadcasting.php this is my dev config
4. Check CORS settings I installed fruitcake/laravel-cors and this is my cors.php config
Maybe for you supports_credentials need to be true
5. Check your channels.php. I have
Make sure to set the broadcast driver to env after that do php artisan config:clear
Use window.Echo.channel('whatever') to join the channel.
Had the exact same issue and was stuck for hours.
I changed 'useTLS' to FALSE in config/broadcasting.php and magically got it working.
I am learning pusher to use it with Laravel, I am trying to subscribe to private channel using Laravel-echo as follow:
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');
window.Echo = new Echo({
Pusher.logToConsole = true; //update: added this
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
encrypted: true
});
var channel = window.Echo.private('roomr');
and per Laravel documentations I have to set authorization in channel.php file so in I wrote in it:
Broadcast::channel('roomr', function ($user) {
logger('hit authorize roomr');
return true;
});
please note that I used logger('hit authorize roomr'); to know if my function is being called, but, when I check the log file it is empty which means that this function is not being called.
using developer tools in google chrome I see there is a post request sent to http://127.0.0.1:8000/broadcasting/auth which return response 200, so, I do not think the authentication is the problem.
Update:
after I added Pusher.logToConsole = true; to my javascript now in chrome console I get:
Pusher : : ["JSON returned from auth endpoint was invalid, yet status
code was 200. Data was: "]
what else I can do? please help me to solve this probem
The problem was in the .env file and I solved it by setting BROADCAST_DRIVER=pusher
I got laravel-echo-server and Laravel 5 application with vuejs, and I'm trying to connect front end to back end via sockets.
I've managed to connect everything together via Echo.channel() method, however it will not subscribe with Echo.private()
This is what I got so far :
Once the page loads I call :
I initilise the Echo via
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001',
csrfToken : Laravel.csrfToken,
auth : {
headers : {
Authorization : "Bearer b6f96a6e99e90dzzzzzzz"
}
}
});
Then I create a new event via vue resourse
Vue.http.get('/api/errors/get');
This fires laravel event(new \App\Events\ErrorsEvent()); event
Which Broadcasts the event privately via
public function broadcastOn()
{
return new PrivateChannel('errors');
}
At this point laravel-echo-server responds with
Channel: private-errors
Event: App\Events\ErrorsEvent
CHANNEL private-errors
Then i try to subscribe to the channel with echo by running
Echo.private('errors')
.listen('ErrorsEvent', (e) => {
this.errors = e.errors;
console.log(e);
});
At which laravel-echo-server responds with
[14:47:31] - xxxxxxxxxxxxxx could not be authenticated to private-errors
Client can not be authenticated, got HTTP status 403
Does anybody know if I'm missing something here?
EDIT
This is my BroadcastServiceProvider
public function boot(Request $request)
{
Broadcast::routes();
/*
* Authenticate the user's personal channel...
*/
Broadcast::channel('App.User.*', function ($user, $userId) {
return (int) $user->id === (int) $userId;
});
}
Also, I've discovered that if I try to subscribe to
Echo.private('App.User.2')
.listen('ErrorsEvent', (e) => {
this.errors = e.errors;
console.log(e);
});
It connects and everything is ok, however it still refuses to connect with the errors channel
My issue was that I hadn't noticed there are two BroadcastServiceProvider::class entries in app/config.php
I had only checked the first one. Once I uncommented App\Providers\BroadcastServiceProvider::class I didn't need to specify the bearer token.
I believe the reason you couldn't connect on the errors channel in your above config is that you need to change your call in your BroadcastServiceProvider (or routes/channels.php) to
Broadcast::channel('errors', function ($user) {
return true; //replace with suitable auth check here
});
I am having trouble with Laravel Echo to listener to Pusher channels. I am not able to get any response in my browser (no console log).
In my bootstrap.js I got.
import Echo from "laravel-echo"
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'myPusherAppKey',
cluster: 'mt1', //My app is US-EAST
encrypted: true
});
I use my browser console and type:
Echo.channel('my-channel')
.listen('my-event', (e) => {
console.log(e);
});
I can see from the Pusher Debug Console that
CONNECTION My app
SUBSCRIBED My-channel
OCCUPIED My-channel
I then use the Pusher Debug Console to send the default event:
Channel: my-channel
Event: my-event
Data: {
"name": "John",
"message": "Hello"
}
However, I do not get any output in my browser console.
If I further type in my browser console:
Echo.leave('my-channel');
I can see from Pusher Debug Console
UNSUBSCRIBED my-channel
VACATED my-channel
How can I get Laravel Echo to listen to Pusher events?
It was a Namespace issue. Laravel documentation explains it.
Echo will automatically assume the events are located in the App\Events namespace
Therefore, the event name must be changed in the Pusher Debug Console as such:
Event: App\Events\my-event