From 0ea97f895b034692be3ad8f108952564f44fbe57 Mon Sep 17 00:00:00 2001 From: mahdihty Date: Mon, 8 Mar 2021 19:04:46 +0330 Subject: [PATCH] complete Fcm push notification channel, message, notification add fcm_token to Fingerprint model --- app/Channels/FcmChannel.php | 72 ++++++++++++++++++- app/Listeners/BusinessUserCreateNotif.php | 8 ++- app/Models/Fingerprint.php | 3 +- app/Models/User.php | 10 +++ app/Notifications/FcmNotification.php | 17 +++-- app/Providers/AppServiceProvider.php | 1 + .../2020_08_18_085017_fingerprints.php | 1 + 7 files changed, 102 insertions(+), 10 deletions(-) diff --git a/app/Channels/FcmChannel.php b/app/Channels/FcmChannel.php index e141bb4..382bfcf 100644 --- a/app/Channels/FcmChannel.php +++ b/app/Channels/FcmChannel.php @@ -3,10 +3,46 @@ namespace App\Channels; +use App\Channels\Messages\FcmMessage; use Illuminate\Notifications\Notification; +use GuzzleHttp\Client as HttpClient; class FcmChannel { + /** + * The API URL for FCM. + * + * @var string + */ + const API_URI = 'https://fcm.googleapis.com/fcm/send'; + + /** + * The HTTP client instance. + * + * @var \GuzzleHttp\Client + */ + protected $http; + + /** + * The FCM API key. + * + * @var string + */ + protected $apikey; + + /** + * Create a new FCM channel instance. + * + * @param \GuzzleHttp\Client $http + * @param string $apiKey + * @return void + */ + public function __construct(HttpClient $http, string $apiKey) + { + $this->http = $http; + $this->apiKey = $apiKey; + } + /** * Send the given notification. * @@ -18,6 +54,40 @@ class FcmChannel { $message = $notification->toFcm($notifiable); - $recipients = $notifiable->routeNotificationFor('fcm', $notification); + $message->to($notifiable->routeNotificationFor('fcm', $notification)); + + if (! $this->apiKey || (! $message->topic && ! $message->to)) { + return; + } + + $this->http->post(self::API_URI, [ + 'headers' => [ + 'Authorization' => "key={$this->apiKey}", + 'Content-Type' => 'application/json', + ], + 'json' => $this->buildJsonPayload($message), + ]); + } + + protected function buildJsonPayload(FcmMessage $message) + { + $payload = array_filter([ + 'priority' => $message->priority, + 'data' => $message->data, + 'notification' => $message->notification, + 'condition' => $message->condition, + ]); + + if ($message->topic) { + $payload['to'] = "/topics/{$message->topic}"; + } else { + if (is_array($message->to)) { + $payload['registration_ids'] = $message->to; + } else { + $payload['to'] = $message->to; + } + } + + return $payload; } } diff --git a/app/Listeners/BusinessUserCreateNotif.php b/app/Listeners/BusinessUserCreateNotif.php index caf33f0..41a3ab5 100644 --- a/app/Listeners/BusinessUserCreateNotif.php +++ b/app/Listeners/BusinessUserCreateNotif.php @@ -2,10 +2,12 @@ namespace App\Listeners; +use App\Channels\FcmChannel; use App\Events\BusinessUserCreate; use App\Models\Business; use App\Models\User; use App\Notifications\DBNotification; +use App\Notifications\FcmNotification; use App\Notifications\MailNotification; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; @@ -36,11 +38,15 @@ class BusinessUserCreateNotif $owners = Business::findOrFail($payload->business)->owners()->where('id', '!=', $new_user->id)->get(); $notif = [ - 'body' => __('notification.'.$payload->data->table_name.'.'.enum('cruds.inverse.'.$payload->data->crud_id.'.singular_name'), ['business' => request('_business_info')['name'], 'user' => $new_user->name]) + 'greeting' => __('notification.'.$payload->data->table_name.'.'.enum('cruds.inverse.'.$payload->data->crud_id.'.singular_name').'.greeting'), + 'subject' => __('notification.'.$payload->data->table_name.'.'.enum('cruds.inverse.'.$payload->data->crud_id.'.singular_name').'.subject'), + 'title' => __('notification.'.$payload->data->table_name.'.'.enum('cruds.inverse.'.$payload->data->crud_id.'.singular_name').'.title'), + 'body' => __('notification.'.$payload->data->table_name.'.'.enum('cruds.inverse.'.$payload->data->crud_id.'.singular_name').'.body', ['business' => request('_business_info')['name'], 'user' => $new_user->name]) ]; $users = $owners->prepend($new_user); Notification::send($users, new MailNotification($notif)); Notification::send($users, new DBNotification($notif)); + Notification::send($users, new FcmNotification($notif)); } } diff --git a/app/Models/Fingerprint.php b/app/Models/Fingerprint.php index 8db0c86..f6cb0d4 100644 --- a/app/Models/Fingerprint.php +++ b/app/Models/Fingerprint.php @@ -6,7 +6,7 @@ use App\Models\Model; class Fingerprint extends Model { - protected $fillable = ['user_id', 'agent', 'ip', 'os', 'latitude', 'longitude', 'token',]; + protected $fillable = ['user_id', 'agent', 'ip', 'os', 'latitude', 'longitude', 'token', 'fcm_token']; protected $table = 'fingerprints'; @@ -25,6 +25,7 @@ class Fingerprint extends Model 'latitude' => 'required', 'longitude' => 'required', 'token' => 'required|string|min:60', + 'fcm_token' => 'nullable', ]; } } diff --git a/app/Models/User.php b/app/Models/User.php index 52767e4..3479edf 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -43,6 +43,16 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac public $detach_relation = false; + /** + * Specifies the user's FCM token + * + * @return string + */ + public function routeNotificationForFcm() + { + return $this->fingerprints->whereNotNull('fcm_token')->pluck('fcm_token')->all(); + } + public function updateRelations() { // projects relations diff --git a/app/Notifications/FcmNotification.php b/app/Notifications/FcmNotification.php index c302a64..cfbd38a 100644 --- a/app/Notifications/FcmNotification.php +++ b/app/Notifications/FcmNotification.php @@ -4,22 +4,22 @@ namespace App\Notifications; use App\Channels\Messages\FcmMessage; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldQueue; -use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; class FcmNotification extends Notification { use Queueable; + public $message; + /** * Create a new notification instance. * * @return void */ - public function __construct() + public function __construct($message) { - // + $this->message = $message; } /** @@ -30,7 +30,7 @@ class FcmNotification extends Notification */ public function via($notifiable) { - return [FcmNotification::class]; + return ['fcm']; } /** @@ -41,8 +41,11 @@ class FcmNotification extends Notification */ public function toFcm($notifiable) { -// return (new FcmMessage()) -// ->to([]) + return (new FcmMessage()) + ->data([ + 'title' => $this->message['title'], + 'body' => $this->message['body'], + ]); } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 7b917de..2dae397 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -6,6 +6,7 @@ use App\Channels\FcmChannel; use Illuminate\Notifications\ChannelManager; use Illuminate\Support\Facades\Notification; use Illuminate\Support\ServiceProvider; +use GuzzleHttp\Client as HttpClient; class AppServiceProvider extends ServiceProvider { diff --git a/database/migrations/2020_08_18_085017_fingerprints.php b/database/migrations/2020_08_18_085017_fingerprints.php index af506ec..6a72833 100644 --- a/database/migrations/2020_08_18_085017_fingerprints.php +++ b/database/migrations/2020_08_18_085017_fingerprints.php @@ -22,6 +22,7 @@ class Fingerprints extends Migration $table->decimal('latitude', 10, 4); $table->decimal('longitude', 11, 4); $table->char('token', 60)->unique(); + $table->text('fcm_token')->unique()->nullable(); $table->timestamps(); }); }