1

In my app with Laravel on back-end users can send messages to each other.

I want to send push notification to app users on new inbox message, but I need to send messages only if user hadn't already read this message.

So I see it that way

  1. On every message sended I need to schedule Laravel notification after 1 minute
  2. if user already received this message I need to cancel this notification

How can dismiss scheduled notification in Laravel? Is this approach fine and actual now?

Class extends Notification

public function via($notifiable)
{
    if($this->dontSend($notifiable)) {
        return [];
    }
    return ['mail'];
}

public function dontSend($notifiable)
{
    return $this->appointment->status === 'cancelled';
} 

Maybe there is more convenient way to handle it? For example, to send push every time but somehow dismiss it showing from app if it's already launched?

moonvader
  • 19,761
  • 18
  • 67
  • 116
  • How do you know whether the user received the notification? Do you keep track of it ? – Ersoy Jun 30 '20 at 18:26
  • If app has enabled push notifications I can track them inside app and make some API request to server if needed – moonvader Jun 30 '20 at 19:50

1 Answers1

1

One way to do it would be something like this;

  • Before you trigger your notification create a unique identifier(sha1 could be an option) with the combination of user_id. Let's say it is SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C. Send it to the notification. Both notification and message will be send at the same time, but notification will have one minute delay.
$identifier = Str::random(64);
$delay = now()->addMinute();
$user->notify((new MyNotification($identifier))->delay($delay));
// send a request that contains identifier.
  • You set this to the Redis with TTL of 2 minutes. It will be gone if there is no action.
Redis::set('SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C', 1, 120);
  • While sending a message to the user, attach this identifier to the message. When user read that message, you make a request to your /read endpoint with all the parameters + the identifier.
  • When you receive the request, delete the key from Redis. (user received the message)
Redis::del('SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C');
  • In your Notification class, implement a small method to check whether the key exists in Redis.
Redis::exists('SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C');
class MyNotification extends BaseNotification
{
    use Queueable;

    private $identifier;

    public function __construct($identifier)
    {
        $this->identifier = $identifier;
    }

    public function via()
    {
        return $this->isValid() ? ['mail'] : [];
    }

    public function isValid()
    {
        return Redis::exists($this->identifier);
    }

    public function toMail()
    {
        // details..
    }
}

It doesn't have to be Redis but it is a perfect match for these kind of key/value structure.

Ersoy
  • 8,816
  • 6
  • 34
  • 48