I'm trying to broadcast a simply test notification to a Laravel app using
Pusher.Within my web page, I've got this JavaScript to listen for the
broadcast in bootstrap.js
import Echo from 'laravel-echo'
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'notmyrealpusherkey',
encrypted: true
});
This is my Notification.vue
Echo.private('App.User.' + this.id)
.notification((notification) => {
console.log(notification);
toastr.info(notification.message, notification.subject);
});
My BroadcastServiceProvider is configured to validate the private channel request:
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int)$user->id === (int)$id;
});
When I check the Pusher console, I can see that the code above successfully subscribed check image here:
https://d1ro8r1rbfn3jf.cloudfront.net/ms_76665/NvEB7BgUnmIA2IR5rO1S3gF1aSP306/Pusher%2B-%2BDebug%2Bconsole%2B2016-12-28%2B19-37-19.png?Expires=1510590716&Signature=Cgykr97sBJUqljH02DfUJztcILiFTMUsUBfsF4kXoYsuJCsHf4lG-3tyhXBmCM70rWGyeCqZ7nrkgqYuOYEYs6Q41nq-ActI9B-vt6fhh5rYgekfe-HM0dERY67OqAbaLVfskq2mUp1Zl7yBPKwgNR9Fw0uzdH8q6ia9L0Za9QBLM1u6Fq3AHoN4OodJaXr5X-ifn1ZVAC7WsYVtLcnWpr3Yx0-w2nzbS4rD2S9KtMnIpsOA8bcHHWW3qoDFm5J0hIB6GVF42-vQTUNo~4B1~L8XT41coOarsF~sTVsaWTYINX93BmpVpKUEDyoarbffEuUsf4sZO6Ee5fILK1wJOQ__&Key-Pair-Id=APKAJHEJJBIZWFB73RSA
When i send notification directly from pusher it will send on console but not send using trigger the image link in description:
https://d1ro8r1rbfn3jf.cloudfront.net/ms_76665/kxgC93iHRWnMPHIdJehBgfsfUG47Lu/Pusher%2B-%2BDebug%2Bconsole%2B2016-12-28%2B19-37-56.png?Expires=1510592071&Signature=f8wvoKGnWLROJ0cXCWqkWz3EVL6rVj6PuJ~-gXpHHgrt7FlZ9gf9YO3lezW2dplmN08419w9qWJh-Cc7cpt4B1dEEwqORjL8eRz528B6l-HKHwnn96iCIE~bfwc80L9qJx9nBbLqTqnEkAlvbugcGlIrr1zB-iMlz9TMloLpYkq-2T-a1Ww8BM3SmbETVunLqhqYxUCbgK3T1swS135tqvg36sA8FWWnBe3djHgSTUuYS6Nv8MyvkF8JS1slxtMzsJ30oEzs5zc~QhEfECfoA8On8VIHP8a4VrOjUyElcrcPHG~7TwnYP8Ajje7O7EW9SNyIV7t3LSyxBGiIdsVDtQ__&Key-Pair-Id=APKAJHEJJBIZWFB73RSA
The NewFriendRequest is just a simple test notification:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class NewFriendRequest extends Notification implements ShouldQueue
{
use Queueable;
public $user;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($user)
{
$this->user = $user;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail','broadcast','database'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('You received a new friend request from ' . $this->user->name)
->action('View Profile', route('profile', ['slug' => $this->user->slug]))
->line('Thank you for using our Tictac!');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
'name' => $this->user->name,
'message' => $this->user->name . ' sent you friend request.'
];
}
}
I also tried triggering it from the Laravel side, but it still doesn't reach the user's browser:
$resp = Auth::user()->add_friend($id);
User::find($id)->notify(new \App\Notifications\NewFriendRequest(Auth::user()));
return $resp;
You're missing the toBroadcast() method in your Notification, as stated by the documentation.
class NewFriendRequest extends Notification implements ShouldQueue
{
public function toBroadcast($notifiable)
{
return new BroadcastMessage([
'message' => 'Insert your message',
'subject' => 'Insert your subject',
]);
}
}
Related
I want tp apply queue for my Notifications, so I implemented that at my Notification which ResetPassword:
class ResetPassword extends Notification implements ShouldQueue
Then I ran php artisan queue:table and migrate it so the table jobs created successfully at the DB.
And also change the QUEUE_CONNECTION to database at .env file and re-run php artisan serve.
But when I test this and clicked on reset password link, a new table row must be added to jobs table but it does not.
And instead of that, this error returns:
ErrorException Undefined property:
App\Notifications\ResetPassword::$queue
...\notification\vendor\laravel\framework\src\Illuminate\Notifications\NotificationSender.php:195
So what is going wrong here ? How can I fix this issue ?
I would really appreciate any idea or suggestion from you guys...
Thanks in advance.
UPDATE #1:
ResetPassword.php:
<?php
namespace App\Notifications;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Lang;
class ResetPassword extends Notification implements ShouldQueue
{
/**
* The password reset token.
*
* #var string
*/
public $token;
/**
* The callback that should be used to build the mail message.
*
* #var \Closure|null
*/
public static $toMailCallback;
/**
* Create a notification instance.
*
* #param string $token
* #return void
*/
public function __construct($token)
{
$this->token = $token;
}
/**
* Get the notification's channels.
*
* #param mixed $notifiable
* #return array|string
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Build the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
}
return (new MailMessage)
->subject('subject goes here')
->line('This email is sent to you')
->action(Lang::get('Reset Password'), url(config('app.url').route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false)))
->line(Lang::get('Until the next 60 minutes you can use this link', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]))
->line(Lang::get('If you did not request a password reset, no further action is required.'));
}
/**
* Set a callback that should be used when building the notification mail message.
*
* #param \Closure $callback
* #return void
*/
public static function toMailUsing($callback)
{
static::$toMailCallback = $callback;
}
}
Look Like you have forgot to use Queueable Trait in your notification
use Illuminate\Bus\Queueable;
class ResetPassword extends Notification implements ShouldQueue
{
use Queueable;
Queueable trait has propety $queue
Ref:https://laravel.com/docs/8.x/notifications#queued-notifications-and-database-transactions
I have a weird issue in my website. I have several Notifications such as Email Verification and Password Reset that are sending properly. However, I made my own notification that sends an url with a UUID to the user and unfortunately, it doesn't send.
I tried every way: 'Notification::route', notify the user directly, nothing works. Actually, notifying the user directly would be bad since I need to send it to an email address not attached to any model.
Anyway, here's the code for the notification. Keep in mind the other notifications work, so I doubt it is the issue.
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class NewEmail extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($uuid)
{
$this->uuid = $uuid;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line(__('messages.newEmailAsked'))
->action(__('messages.newEmailConfirm'), config('app.frontend_url') . '/verify-new-email?code=' . $this->uuid)
->line(__('messages.newEmailIgnore'));
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
public function addNewEmail($email) {
if(User::where('email', $email)->count() === 0) {
$uuid = Str::uuid();
NewEmail::create(['email' => $email, 'unique_code' => $uuid, 'user_id' => $this->id]);
Notification::route('mail', $email)->notify(new \App\Notifications\NewEmail($uuid));
} else {
return 'Email already exists.';
}
}
I really don't get why this notification isn't sent while the other are...
Weirdly enough, the problem fixed itself when I did the actual path the user would take instead of using Tinker.
Just had to $user->addNewEmail($newEmailHere) and it worked properly...
You have not defined the $uuid variable in your Queueable class
i want to get email notification each time a new user is registered but after creating php artisan make:notification Taskcompleted and added Notification::route('mail','admin#gmail.com')->notify(new TaskCompleted()); like this in my contoller
public function store(Request $request){
$employee = request()->validate([
'employee_id' => 'required|max:250',
'name' => 'required|max:100',
'place_of_birth' => 'nullable|max:100',]);
Notification::route('mail','admin#gmail.com')->notify(new TaskCompleted());
i keep getting this error
Trying to access array offset on value of type null i have imported the necessary class and configured my .env file with mailtrap,still yet same error
taskcompleted file
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class TaskCompleted extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
ok, I got the solution I was using PHP 7.4 for laravel 5.5 so I downgraded it to PHP 7.2 works fine now
In my web app I have added the notification functionalities.
There are 3 notification class.
App/Notifications/
NotifWhenLiked.php
NotifyWhenStoryCommented.php
NotifyWhenAuthorFollowed.php
I want to make these task with one single Notification class. Is there any easiest way to solve this ?
Here is the code of one class
<?php
namespace App\Notifications;
use App\Http\Resources\Users;
use App\Model\User;
use App\Model\Story;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class NotifyWhenLiked extends Notification implements ShouldQueue
{
use Queueable;
public $user;
public $story;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct(Story $story, User $user)
{
$this->user = $user;
$this->story = $story;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['database','broadcast'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toDatabase($notifiable)
{
return [
'notification' => "<strong>".$this->user->name."</strong>". ' liked your story '. "<strong>".$this->story->title."</strong>",
'Storylink' => '/story/'.$this->story->url_key,
'Userlink' => '/a/'.$this->user->profile->username
];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
'notification' => $this->user->name. ' liked your story '. "<strong>".$this->story->title."</strong>",
'username' => $this->user->profile->username,
];
}
}
You might try to store the different notification types into an array e.g. a config file.
return [
'when_liked' => [
'notification_text' => '%s liked your story %s',
'story_link' => '/story/%s'
],
'when_commented' => [
'notification_text' => '%s commented on your story %s',
'story_link' => '/story/%s'
]
]
You can make a general Notification Class, which takes care about handling the notification stuff.
$whenLikedNotification = new YourCustomNotificationClass('when_liked');
$whenLikedNotification->trigger();
In the Constructor you can handle the config stuff.
I think you can use a event to do it
Create a event and call all listener(WhenLiked, WhenStoryCommented, WhenAuthorFollowed) that is related with event
When I add a friend it change status/button my side but not another side.
I am using Pusher, Laravel and Vue.js.
My problem is that if am sending friend request it will send to other user and notify to me but not to other side. I don't know what I am doing wrong.
This is my channel code.
Broadcast::channel('App.User.{id}', function ($user, $id){
return (int) $user->id === (int) $id;
});
This is my NewFriendRequest.php code
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class NewFriendRequest extends Notification implements ShouldQueue
{
use Queueable;
public $user;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($user)
{
$this->user = $user;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail','broadcast','database'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('You received a new friend request from ' . $this->user->name)
->action('View Profile', route('/profile', ['slug' => $this->user->slug]))
->line('Thank you for using our Tictac!');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
'name' => $this->user->name,
'message' => $this->user->name . ' sent you friend request.'
];
}
}
This is my notification.vue code
<script>
export default {
mounted() {
this.listen()
},
props: ['id'],
methods: {
listen() {
Echo.private('App.User.' + this.id)
.notification( (notification) => {
noty({
type: 'success',
layout: 'bottomLeft',
text: notification.name + notification.message,
timeout: 5000
}).show()
document.getElementById("noty_audio").play()
})
}
}
}
This is my Example.vue code that can use to send friend request to
other user.
add_friend(){
this.loading = true
axios.get('http://localhost/Tictac/add_friend/' +
this.profile_user_id )
.then ((r) => {
if(r.data == 1)
this.status = 'waiting'
new Noty({
type: 'success',
layout: 'bottomLeft',
text: 'Friend request sent .',
timeout: 5000
}).show()
this.loading = false
})
},
My bootstrap.js file
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
authEndpoint: 'http://localhost/Tictac/broadcasting/auth',
broadcaster: 'pusher',
key: '58f16da7e24fa9505db8',
cluster: 'eu',
encypted: true
});
Pusher.log = function(message){
window.console.log(message)
}
App.js
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example', require('./components/Example.vue'));
Vue.component('notification', require('./components/Notification.vue'));
const app = new Vue({
el: '#app'
});