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

seandelaney's avatar

Notifications not saved to database

Setup a notification to send an email, save to the database and broadcast.

Sending the email and broadcasting works fine.

Not sure what is wrong. I have other notifications that save to the database, which works fine and the code is exactly the same.

Here is my notification:

<?php

namespace App\Notifications;

use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Mail\OrderPlaced as OrderPlacedMail;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\BroadcastMessage;

class OrderPlaced extends Notification implements ShouldQueue
{
    use Queueable;
    
    /**
     * Information about the order.
     *
     * @var string
     */
    protected $order;
    
    /**
     * Information about the subject.
     *
     * @var string
     */
    protected $subject;
    
    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct(Order $order, string $subject = 'Order Placed')
    {
        $this->order = $order->load('user', 'status', 'location', 'order_type', 'shipping_method');
        
        $this->subject = $subject;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param   mixed  $notifiable
     * @return array
     */
    public function via($notifiable) : array
    {
        return ['mail', 'database', 'broadcast'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param   mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new OrderPlacedMail($this->order))->to($this->order->user->email)->subject($this->subject);
    }
    
    /**
     * Get the broadcastable representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return BroadcastMessage
     */
    public function toBroadcast($notifiable)
    {
        $data = [
            'order' => $this->order->load('user', 'status', 'location', 'order_type', 'shipping_method'),
        ];

        return (new BroadcastMessage($data))->onQueue('orders.broadcasts');
    }

    /**
     * Get the array representation of the notification.
     *
     * @param   mixed   $notifiable
     * @return  array
     */
    public function toDatabase($notifiable) : array
    {
        return [
            'order' => $this->order->load('user', 'status', 'location', 'order_type', 'shipping_method'),
        ];
    }
}

Any help would be grateful.

Thanks Sean

0 likes
6 replies
seandelaney's avatar

I have already watched this episode and does not resolve my issue.

mindz's avatar

provide notifications table migration please

seandelaney's avatar

@mindz

Sure.

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateNotificationsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::enableForeignKeyConstraints();
        
        Schema::create('notifications', function (Blueprint $table) {
            $table->engine = 'InnoDB ROW_FORMAT=DYNAMIC';
            
            $table->uuid('id')->primary();
            
            $table->string('type');
            
            $table->morphs('notifiable');
            
            $table->text('data');
            
            $table->timestamp('read_at')->nullable();
            $table->timestamp('created_at')->useCurrent();
            $table->timestamp('updated_at')->useCurrent();
        });
        
        Schema::table('notifications', function (Blueprint $table) {
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('notifications');
    }
}
seandelaney's avatar

After some debugging, I exclusively called a notification to save to the database only and got the following.

[2017-09-27 17:05:10] local.ERROR: Call to a member function create() on null {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Call to a member function create() on null at /Users/seandelaney/Sites/XXXX/vendor/laravel/framework/src/Illuminate/Notifications/Channels/DatabaseChannel.php:19)
[stacktrace]
#0 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(113): Illuminate\\Notifications\\Channels\\DatabaseChannel->send(Object(Illuminate\\Notifications\\AnonymousNotifiable), Object(App\\Notifications\\OrderPlaced))
#1 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(89): Illuminate\\Notifications\\NotificationSender->sendToNotifiable(Object(Illuminate\\Notifications\\AnonymousNotifiable), '6b6afe81-1969-4...', Object(App\\Notifications\\OrderPlaced), 'database')
#2 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.php(50): Illuminate\\Notifications\\NotificationSender->sendNow(Array, Object(App\\Notifications\\OrderPlaced), Array)
#3 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Notifications/SendQueuedNotifications.php(57): Illuminate\\Notifications\\ChannelManager->sendNow(Object(Illuminate\\Notifications\\AnonymousNotifiable), Object(App\\Notifications\\OrderPlaced), Array)
#4 [internal function]: Illuminate\\Notifications\\SendQueuedNotifications->handle(Object(Illuminate\\Notifications\\ChannelManager))
#5 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(29): call_user_func_array(Array, Array)
#6 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#8 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Container/Container.php(549): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#9 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(94): Illuminate\\Container\\Container->call(Array)
#10 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(114): Illuminate\\Bus\\Dispatcher->Illuminate\\Bus\\{closure}(Object(Illuminate\\Notifications\\SendQueuedNotifications))
#11 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Notifications\\SendQueuedNotifications))
#12 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#13 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(49): Illuminate\\Bus\\Dispatcher->dispatchNow(Object(Illuminate\\Notifications\\SendQueuedNotifications), false)
#14 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(76): Illuminate\\Queue\\CallQueuedHandler->call(Object(Illuminate\\Queue\\Jobs\\DatabaseJob), Array)
#15 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(320): Illuminate\\Queue\\Jobs\\Job->fire()
#16 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(270): Illuminate\\Queue\\Worker->process('database', Object(Illuminate\\Queue\\Jobs\\DatabaseJob), Object(Illuminate\\Queue\\WorkerOptions))
#17 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(114): Illuminate\\Queue\\Worker->runJob(Object(Illuminate\\Queue\\Jobs\\DatabaseJob), 'database', Object(Illuminate\\Queue\\WorkerOptions))
#18 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(101): Illuminate\\Queue\\Worker->daemon('database', 'orders.notifica...', Object(Illuminate\\Queue\\WorkerOptions))
#19 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(85): Illuminate\\Queue\\Console\\WorkCommand->runWorker('database', 'orders.notifica...')
#20 [internal function]: Illuminate\\Queue\\Console\\WorkCommand->handle()
#21 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(29): call_user_func_array(Array, Array)
#22 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#23 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#24 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Container/Container.php(549): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#25 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Illuminate\\Container\\Container->call(Array)
#26 /Users/seandelaney/Sites/XXXXXX/vendor/symfony/console/Command/Command.php(264): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#27 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Console/Command.php(167): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#28 /Users/seandelaney/Sites/XXXXXX/vendor/symfony/console/Application.php(888): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 /Users/seandelaney/Sites/XXXXXX/vendor/symfony/console/Application.php(224): Symfony\\Component\\Console\\Application->doRunCommand(Object(Illuminate\\Queue\\Console\\WorkCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 /Users/seandelaney/Sites/XXXXXX/vendor/symfony/console/Application.php(125): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#31 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Console/Application.php(88): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#32 /Users/seandelaney/Sites/XXXXXX/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(121): Illuminate\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#33 /Users/seandelaney/Sites/XXXXXX/artisan(37): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#34 {main}
"} 
seandelaney's avatar
seandelaney
OP
Best Answer
Level 6

So I managed to resolve my issue...debugging line by line...

So I was calling my notification like this:

// Sends an order placed notification to the user. Stick the notification in the "orders" queue to run in 5 minutes.
$this->user->notify((new OrderPlaceNotification($event->order))->delay($time)->onQueue('orders.notifications'));
        
// Sends an order placed notification to the supplier. Sticks the notification in the "orders" queue to run in 5 minutes.
Notification::route('mail', $this->supplierEmail)->notify((new OrderPlaceNotification($event->order))->delay($time)->onQueue('orders.notifications'));

Trying to call Notification::route(...) was my issue.

Notifications were sent by email, saved to the database and broadcasted in the first call. It was my 2nd call that failed all along.

Because I was trying to call the same OrderPlaceNotification in both calls, the 2nd call didn't have a User class/instance associated with it, so saving to the database was always going to fail.

2 likes

Please or to participate in this conversation.