Skip to content

Instantly share code, notes, and snippets.

@puncoz
Created August 31, 2020 08:51
Show Gist options
  • Save puncoz/9cf9ca47ca8eee59499704047a0749d3 to your computer and use it in GitHub Desktop.
Save puncoz/9cf9ca47ca8eee59499704047a0749d3 to your computer and use it in GitHub Desktop.
FCM Notification
<?php
try {
$this->notificationService->send($notification->data, $notification->userOrPartnerId, $notification->type, $notification->currentUser);
} catch (DeviceIdNotRegisteredException $exception) {
logger()->info(
sprintf("Push notification failed due to %s", $exception->getMessage())
);
} catch (\Exception $exception) {
logger()->error(
sprintf("Push notification failed due to %s", $exception->getMessage())
);
}
<?php
namespace App\Notification;
use App\Exceptions\FcmKeyNotSetException;
use GuzzleHttp\Client;
/**
* Class Notification
* @package App\Notification
*/
class Notification
{
const FCM_URL = 'https://fcm.googleapis.com/fcm/send';
protected $data;
protected $client;
protected $headers;
public function __construct()
{
$this->client = new Client;
}
/**
* @param string $to
* @param array $data
*
* @return $this
* @throws FcmKeyNotSetException
*/
public function prepare(string $to, array $data)
{
$this->data = [
'data' => $data,
'to' => $to,
];
$fcmServerKey = config('config.fcm_server_key');
if ( !$fcmServerKey ) {
throw new FcmKeyNotSetException();
}
$this->headers = ['Content-Type' => 'application/json', 'Authorization' => sprintf('key=%s', $fcmServerKey)];
return $this;
}
/**
* Send post request.
*
*/
public function send()
{
$response = $this->client->request(
'POST',
self::FCM_URL,
[
'headers' => $this->headers,
'json' => $this->data,
]
);
logger()->info(
'Push Notification sending log',
[
$this->data,
$response->getBody()->getContents(),
]
);
}
}
<?php
namespace App\Api\Services\Notification;
use App\Constants\Constants;
use App\Exceptions\Auth\DeviceIdNotRegisteredException;
use App\Exceptions\FcmKeyNotSetException;
use App\Models\Partner\Partner;
use App\Repositories\NotificationLog\INotificationLogRepository;
use App\Repositories\Partner\IPartnerRepository;
use App\Repositories\Users\IUserRepository;
use App\Utils\Notification;
use Illuminate\Support\Collection;
class NotificationService
{
/**
* @var Notification
*/
protected $notification;
/**
* @var INotificationLogRepository
*/
protected $notificationLogRepository;
/**
* @var IUserRepository
*/
protected $userRepository;
/**
* NotificationService constructor.
*
* @param Notification $notification
* @param INotificationLogRepository $notificationLogRepository
* @param IUserRepository $userRepository
*/
function __construct(Notification $notification, INotificationLogRepository $notificationLogRepository, IUserRepository $userRepository)
{
$this->notification = $notification;
$this->notificationLogRepository = $notificationLogRepository;
$this->userRepository = $userRepository;
}
/**
* Send notification to user's devices
*
* @param array $data
* @param int $userOrPartnerId
* @param string $type
* @param int $currentUser
*
* @throws DeviceIdNotRegisteredException
*/
public function send(array $data, int $userOrPartnerId, string $type = Constants::PUSH_INDIVIDUAL, int $currentUser = 1)
{
if ( $type === Constants::PUSH_INDIVIDUAL ) {
$this->sendToIndividualDevice($data, $userOrPartnerId);
} else {
if ( $type === Constants::PUSH_ALL ) {
$this->sendToAllDevices($data, $currentUser);
} else {
if ( $type === Constants::PUSH_PARTNER ) {
$this->sendToPartner($data, $userOrPartnerId, $currentUser);
}
}
}
}
/**
* @param array $data
* @param int $userId
*
* @return Collection
* @throws DeviceIdNotRegisteredException
*/
protected function sendToIndividualDevice(array $data, int $userId): Collection
{
$user = $this->userRepository->with('devices')->find($userId);
if ( $user->devices->count() === 0 ) {
throw new DeviceIdNotRegisteredException($user->id);
}
return $user->devices->each(
function ($device) use ($data, $user) {
try {
$this->notification->prepare($device->device_id, $data)->send();
$this->notificationLogRepository->create(['user_id' => $user->id, 'device_id' => $device->device_id, 'data' => $data]);
} catch (FcmKeyNotSetException $exception) {
logger()->error($exception->getMessage());
} catch (\Exception $exception) {
logger()->error($exception);
}
}
);
}
/**
* @param array $data
* @param int $currentUser
*/
protected function sendToAllDevices(array $data, int $currentUser)
{
try {
$this->notification->prepare('/topics/general', $data)->send();
$this->notificationLogRepository->create(['user_id' => $currentUser, 'device_id' => 'general', 'data' => $data]);
} catch (\Exception $exception) {
logger()->error($exception);
}
}
/**
* @param array $data
* @param int $partnerId
* @param int $currentUser
*/
protected function sendToPartner(array $data, int $partnerId, int $currentUser)
{
/** @var Partner $partner */
$partner = app(IPartnerRepository::class)->find($partnerId);
$to = sprintf("/topics/%s_%d", Constants::PUSH_PARTNER, $partner->id);
try {
$this->notification->prepare($to, $data)->send();
$this->notificationLogRepository->create(['user_id' => $currentUser, 'device_id' => $to, 'data' => $data]);
} catch (FcmKeyNotSetException $exception) {
logger()->error($exception->getMessage());
} catch (\Exception $exception) {
logger()->error($exception);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment