Why I got duplicate key error collection: sessions index error with jenssegers/mongodb?

337 views Asked by At

I started new laravel 9 (with jet and inertia, without team) app with "jenssegers/mongodb": "^3.9" installed. I changed connection to mongo MngProducts database and run migrations.

But running homepage with controller defined I got error on second request :

E11000 duplicate key error collection: MngProducts.sessions index: id_1 dup key: { id: "loBh99XTp9cm3Qj17YqKhVFTuxM8bvpd14wczWQa" }

In Compass I see 1 row in sessions : https://prnt.sc/irFNeSAU-zN4

I migrated all default 4 laravel tables(without any data in them) and why I have this error and how that can be fixed?

Thanks!

2

There are 2 answers

1
mstdmstd On BEST ANSWER

Setting in .env file :

SESSION_DRIVER=file

fixed this issue.

0
Javokhir Abdirasulov On

For mongodb database driver you have to override "read" method of the DatabaseSessionHandler. There is a problem with find() method.

Then how to use database as session driver with mongodb in Laravel ?

Solution for the problem:

Step 1. Create SessionServiceProvider.php file in app/Providers folder.

<?php

namespace App\Providers;

use App\Session\MongoSessionHandler;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\ConnectionInterface;



class SessionServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }



    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot(ConnectionInterface $connection)
    {
        Session::extend('database', function ($app) use ($connection) {
            $table   =  config('session.table');
            $minutes =  config('session.lifetime');
            return new MongoSessionHandler($connection, $table, $minutes);
        });
    }
}

Step 2. Create MongoSessionHandler.php in app/Session folder.

<?php

namespace App\Session;

use Illuminate\Session\DatabaseSessionHandler;

class MongoSessionHandler extends DatabaseSessionHandler
{
    /**
     * {@inheritdoc}
     */
    public function read($sessionId): false|string
    {
        $session = (object) $this->getQuery()->where('id', $sessionId)->first();

        if ($this->expired($session)) {
            $this->exists = true;

            return '';
        }

        if (isset($session->payload)) {
            $this->exists = true;

            return base64_decode($session->payload);
        }

        return '';
    }
}

Step 3. Register new service provider.

(Laravel 8x-9x-10x config/app.php) ,

 'providers' => ServiceProvider::defaultProviders()->merge([
     App\Providers\SessionServiceProvider::class,
     ...
]

(Laravel 11x bootstrap/app.php):

return [
    App\Providers\SessionServiceProvider::class,
    ...
];