Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "expo_tickets_ticket_id_unique" #35

Open
Arsiievych opened this issue Oct 30, 2024 · 0 comments

Comments

@Arsiievych
Copy link

Arsiievych commented Oct 30, 2024

I encountered an issue when sending multiple notifications using notify().

Steps to Reproduce:

$user = User::find(1);
$user2 = User::find(2);

$user->notify(new NewMessageNotification());
$user2->notify(new UpcomingCallNotification());

Expected Result:
Notifications should be sent without exceptions.

Actual Result:

SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "expo_tickets_ticket_id_unique"
DETAIL: Key (ticket_id)=(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXdb407) already exists.

INSERT INTO
  "expo_tickets" ("ticket_id", "token", "updated_at", "created_at")
VALUES
  (
    XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXX9fbf2,
    ExponentPushToken[XXXXXXXXXXXXXXXX],
    2024-10-30 15:22:05,
    2024-10-30 15:22:05
  ) returning "id"

It is important to note that the issue does not depend on which user the notify method is executed for, nor does it vary based on the specific notification being sent. The error occurs consistently across different users and notification types.

After investigating, I found that the problems arise here in the ExpoNotificationsService::checkAndStoreTickets(Collection $tokens), particularly in this line: $this->ticketStorage->store($ticket->ticketId, $tokens->get($index));

Variable dumps from the first call ($user->notify(new NewMessageNotification());):


$this->tickets: Illuminate\Support\Collection Object
(
    [items:protected] => Array
        (
            [0] => YieldStudio\LaravelExpoNotifier\Dto\PushTicketResponse Object
                (
                    [status] => ok
                    [ticketId] => XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXX9fbf2
                    [message] => 
                    [details] => 
                )
        )
    [escapeWhenCastingToString:protected] => 
)
  
$tokens: Illuminate\Support\Collection Object
(
    [items:protected] => Array
        (
            [0] => ExponentPushToken[XXXXXXXXXXXXXXXX]
        )
    [escapeWhenCastingToString:protected] => 
)

From the next call ($user2->notify(new UpcomingCallNotification());):

$this->tickets: Illuminate\Support\Collection Object
(
    [items:protected] => Array
        (
            [0] => YieldStudio\LaravelExpoNotifier\Dto\PushTicketResponse Object
                (
                    [status] => ok
                    [ticketId] => XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXX9fbf2
                    [message] => 
                    [details] => 
                )
            [1] => YieldStudio\LaravelExpoNotifier\Dto\PushTicketResponse Object
                (
                    [status] => ok
                    [ticketId] => XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXdbb49
                    [message] => 
                    [details] => 
                )
        )
    [escapeWhenCastingToString:protected] => 
)
  
$tokens: Illuminate\Support\Collection Object
(
    [items:protected] => Array
        (
            [0] => ExponentPushToken[XXXXXXXXXXXXXXXX]
        )
    [escapeWhenCastingToString:protected] => 
)

It tries to re-store record [0], instead of storing only [1].

I also couldn’t find any logic to clear $this->tokens, which means that beyond the storage problem, I encounter issues using the notify method in a queue container. Over time, $this->tokens accumulates many records.

I was also able to reproduce the issue by executing the following in Tinker:

php artisan tinker
$user = User::find(1);
$user->notify(new NewMessageNotification());
$user->notify(new NewMessageNotification());

This results in the following error:

Illuminate\Database\UniqueConstraintViolationException  
SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "expo_tickets_ticket_id_unique"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant