I am trying to set up database notification, but the data I am sending for the 'data' column isn't showing up...
My notification class:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use App\User;
use App\Admin;
class UserAddedToStudio extends Notification implements ShouldQueue
{
use Queueable;
public $user;
public $admin;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct(User $user, Admin $admin)
{
$this->user = $user;
$this->admin = $admin;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail', 'database'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Welcome to '.$this->admin->name.'\'s studio')
->line('Hi '.$this->user->name.'. Your request to join '.$this->admin->name.'\'s studio has been accepted! Now you can start registering for lessons.')
// ->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 toDatabase($notifiable)
{
return [
'message' => 'You have been added to the studio'
];
}
}
In my notifications table on MySQL all the columns are filled except for the data column. There I only get an empty array []. but why?? so frustrating.... :(
Here is the screenshot from my phpmyadmin.
Try to use toArray() instead of toDatabase()
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
'message' => 'You have been added to the studio'
];
}
as you use Queue you should restart the queue worker.
php artisan queue: work
Remember, queue workers, are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to restart your queue workers. In addition, remember that any static state created or modified by your application will not be automatically reset between jobs.
Related
I am using Laravel 8 Jetstream.
Given that I am using an additional and external database, I need to send email notifications to users, whose info is in that external database, where the email column name is different; let's say "electronicmail".
In the official docs it says:
Remember, you may use the Notifiable trait on any of your models. You
are not limited to only including it on your User model.
So I got this external model:
ExternalUser.php
<?php
namespace App\Models\ExternalDatabase;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
class ExternalUser extends Model
{
use Notifiable;
/**
* External DB connection
*
* #var string
*/
protected $connection='externalissima';
/**
* The table associated with the model.
*
* #var string
*/
protected $table='External-users';
/**
* Indicates whether or not the model should be timestamped.
*
* #var bool
*/
public $timestamps = false;
}
That external External-users table does not have the email column, but as electronicmail.
So, whenever I use:
$ext_user->notify(new \App\Notifications\Test());
The \App\Notifications\Test() notification class is not working, since I guess because there's no exact email column name.
Then how do I customize the email column to make it work?
After hours of searching, I have read also in the same docs that you can make use of on-demand notifications like so:
Route::get('notification', function (){
Auth()->user()->notify(new \App\Notifications\Test()); //THIS IS WORKING
Illuminate\Support\Facades\Notification::route('email',
['tester#mail.com','John Doe']
)->notify(new \App\Notifications\Test()); //THIS, what I need, IS NOT WORKING, why???
});
And my test notification looks like:
Notifications/Test.php
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class Test extends Notification implements ShouldQueue
{
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)
->subject('Test notification')
->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 [
//
];
}
}
In my case, the notifications for the models/User.php are working fine.
However,
Illuminate\Support\Facades\Notification::route('email',
['tester#mail.com','John Doe']
)->notify(new \App\Notifications\Test());
this is not working with on demand notifications with a custom email, why?
How do I fix this? What am I missing?
Notifications are not recording data in the database. I tried it with toDatabase and it also didn't work. Look:
<?php
namespace App\Notifications;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class NovoSeguidor extends Notification implements ShouldQueue
{
use Queueable;
private $user;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct(user $user)
{
$this->user = $user;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail','database'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line("Novo seguidor: {$this->user}")
->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 [
'teste' => 'Hello',
];
}
}
My column data return [].
I tried both ways, both using toArray() and toDatabase(), both return an empty array.
I've tried everything and I don't see anything that could be causing it. Can anyone help me identify the problem?
i'm using laravel mail notification and i have problem in the url button i have http://127.0.0.1 instead of http://127.0.0.1:8000 and when i clic at the button in email i redirected in failued url because :8000
is missed.
how i can fix this problem please ?
this my code in notification class
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\BroadcastMessage;
use Illuminate\Notifications\Notification;
class NewProject extends Notification implements ShouldQueue
{
use Queueable;
public $data;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($data)
{
$this->data=$data;
}
/**
* 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('New Project :' . $this->data['projet'])
->action('New project', url('/detail/'.$this->data['id']))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toDatabase($notifiable)
{
return [
//
];
}
}```
The base app URL is configured inside the .env file on the variable APP_URL. So you must set:
APP_URL=http://127.0.0.1:8000
In your environment file.
I use database notifications, in notification code I have method toDatabase:
public function toDatabase($notifiable)
{
$user = \App\SomeUsers::where('id', $notifiable->id)->first();
return [
'message' => $message,
];
}
it returns data array which is being sent to database channel mentioned in via method of current notification:
public function via($notifiable)
{
return ['database'];
}
Everything is as usual, BUT... The problem is I need id of notification in database here in current notification file so that I could broadcast message (from current notification file) to frontend which contains id of notificaion in db (so I could somehow identify it to mark as read). How to get it?
P.S. Moreover, database notification may be queueable, so... it seems that I can't get id...
P.P.S Another words I need broadcast message which contains ["id" => "id of just added corresponding database notification"].
<?php
namespace App\Notifications;
use App\Channels\SocketChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Redis;
class MyCustomNotification extends Notification implements ShouldQueue
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($param)
{
$this->param = $param;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
$channels = ['database'];
return $channels;
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toDatabase($notifiable)
{
info("This is the current notification ID, it's generated right here before inserting to database");
info($this->id);
return [
'id' => **$this->id**,
'message' => 'Notification message',
];
}
}
$this->id solves the problem.
https://laracasts.com/discuss/channels/laravel/get-database-notification-id-in-push-notification
P.S. I want to draw attention to one fact. When I posted this question, I knew about $this->id, but I couldn't make it work. The reason was: when I dive deeper to my target code from the top level I made changes to code, but they didn't apply. The reason is queues. You need to restart laravel worker to apply settings as Laravel caches logic or you need temporarily delete those: implements ShouldQueue and use Queueable.
In order to retrieve the actual ID of the notifications table in Laravel, you need to cast the ID column to string. First, you need to create a new model called, Notification.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Notification extends Model
{
/**
* Cast variables to specified data types
*
* #var array
*/
protected $casts = [
'data' => 'array',
'id' => 'string'
];
}
This way, if you retrieve the model, it will give you the actual ID of the table.
{
"id": "212829d6-5579-449f-a8e5-e86f0a08e0f9",
"type": "App\\Notifications\\CronFailureNotification",
....
}
The accepted answer did not provide a solution for me in Laravel 8. To properly get the id of the notification, listen for the NotificationSent event and retrieve the id there. Example code:
EventServiceProvider.php
protected $listen = [
NotificationSent::class => [
DispatchBroadcastNotification::class
]
];
DispatchBroadcastNotification.php
<?php
namespace App\Listeners;
use App\Notifications\BroadcastNotification;
use Illuminate\Notifications\Events\NotificationSent;
class DispatchBroadcastNotification
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param NotificationSent $event
* #return void
*/
public function handle(NotificationSent $event)
{
$event->notifiable->notify(
new BroadcastNotification($event->notification->id)
);
}
}
BroadcastNotification.php
<?php
namespace App\Notifications;
use App\Models\Tenant\User;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Notifications\Messages\BroadcastMessage;
use Illuminate\Notifications\Notification;
class BroadcastNotification extends Notification implements ShouldBroadcast
{
public $notificationId;
public function __construct($notificationId)
{
$this->notificationId = $notificationId;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via(User $notifiable): array
{
return ['broadcast'];
}
public function toBroadcast(User $notifiable)
{
return new BroadcastMessage([
'notificationId' => $this->notificationId
]);
}
}
When I do this, the user receives email without error:
Notification::send($user, new TicketNotification($details));
But, when I do this, the user also receives an email, but with an error in the screenshot below
Notification::route('mail', 'email_of_non-db_user')->notify(new TicketNotification($details));
Error: Call to a member function create() on null
Do have any idea why? How can I avoid this error?
I have to use On Demand Notification because I need to send a notification to someone who is not stored as a "user".
i think try this one
in TicketNotification update via method with this for only send to mail.
But u r also saved notification into database..
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
Thanks Jignesh, your answer works.
Sorry Thamer, I should have posted the whole code from the beginning.
Before, it was :
return ['mail','database'];
Now only :
return ['mail'];
Then, there is no error anymore.
Here my TicketNotification that made the error:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class TicketNotification extends Notification
{
use Queueable;
private $details;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($details)
{
$this->details = $details;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail','database'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject($this->details['subject'])
->greeting($this->details['title'])
->line($this->details['body'])
->line($this->details['links'])
;
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toDatabase($notifiable)
{
return [
'order_id' => $this->details['order_id']
];
}
}
Add this to your via method to use the same Notification for all your issues:
public function via($notifiable)
{
$availableChannels = [
'mail' => 'mail',
'database' => 'database',
'slack' => 'slack',
'telegram' => TelegramChannel::class
];
$channels = [];
foreach ($availableChannels AS $channel => $driver) {
if ($notifiable->routeNotificationFor($channel)) {
$channels[] = $driver;
}
}
return $channels;
}
You can now use On-Demand Notifications or fire the notificaton on users, without having to make multiple Notifications for each Channel or ON-DEMANDS etc...