diff --git a/.stubs.php b/.stubs.php index 3bdcc2b..08eb14a 100644 --- a/.stubs.php +++ b/.stubs.php @@ -14,7 +14,6 @@ */ class Notification { - public function sendToFCM(Model $user, array $data=[]): static {} public function sendToEmail(Model $user): static {} public function sendToSlack(Model $user): static {} public function sendToDiscord(Model $user): static {} diff --git a/README.md b/README.md index ddaddd0..fbbaa0b 100644 --- a/README.md +++ b/README.md @@ -183,10 +183,43 @@ to make FCM Notification Work you need to install [Filament Settings Hub](https: ) ``` -now go to settings hub and update FCM settings by add admin-auth.json file and update fcm settings than run this command +than you need to install `filament-fcm` package by use this command ```bash -php artisan filament-alerts:fcm +composer require tomatophp/filament-fcm +``` + +and add the service provider plugin + +```php +->plugin(\TomatoPHP\FilamentFcm\FilamentFcmPlugin::make()) +``` + +now you need to update config + + +```dotenv +# Firebase Project +FIREBASE_API_KEY= +FIREBASE_AUTH_DOMAIN= +FIREBASE_DATABASE_URL= +FIREBASE_PROJECT_ID= +FIREBASE_STORAGE_BUCKET= +FIREBASE_MESSAGING_SENDER_ID= +FIREBASE_APP_ID= +FIREBASE_MEASUREMENT_ID= + +# Firebase Cloud Messaging +FIREBASE_VAPID= + +# Firebase Alert Sound +FCM_ALERT_SOUND= +``` + +than run this command + +```bash +php artisan filament-fcm:install ``` it will generate FCM worker for you to make notifications working on the background. diff --git a/composer.json b/composer.json index 104864d..606b4ef 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,6 @@ "filament/spatie-laravel-translatable-plugin": "^3.2", "tomatophp/filament-settings-hub": "^1.0", "tomatophp/discord-notifications": "^1.0", - "tomatophp/fcm-notifications": "^1.0", "tomatophp/pusher-notifications": "^1.0", "tomatophp/messagebird-notifications": "^1.0", "laravel/slack-notification-channel": "^3.2" diff --git a/src/Console/FilamentAlertsFCM.php b/src/Console/FilamentAlertsFCM.php deleted file mode 100644 index ccbf213..0000000 --- a/src/Console/FilamentAlertsFCM.php +++ /dev/null @@ -1,60 +0,0 @@ -info('Install FCM Worker'); - $this->generateStubs( - __DIR__ . '/../../stubs/firebase.stub', - public_path('firebase-messaging-sw.js'), - [ - 'apiKey' => setting('fcm_apiKey'), - 'authDomain' => setting('fcm_authDomain'), - 'databaseURL' => setting('fcm_database_url'), - 'projectId' => setting('fcm_projectId'), - 'storageBucket' => setting('fcm_storageBucket'), - 'messagingSenderId' => setting('fcm_messagingSenderId'), - 'appId' => setting('fcm_appId'), - 'measurementId' => setting('fcm_measurementId'), - 'sound' => setting('notifications_sound') ? "var audio = new Audio('".setting('notifications_sound')."');\n audio.play();": null - ] - ); - $this->info('Filament Alerts FCM installed successfully.'); - } -} diff --git a/src/FilamentAlertsPlugin.php b/src/FilamentAlertsPlugin.php index f8877a1..b25b5ce 100644 --- a/src/FilamentAlertsPlugin.php +++ b/src/FilamentAlertsPlugin.php @@ -86,14 +86,6 @@ public function getId(): string "name" => 'Discord', "id" => "discord" ], - [ - "name" => 'FCM Web', - "id" => "fcm-web" - ], - [ - "name" => 'FCM Mobile', - "id" => "fcm-api" - ], [ "name" => 'Reverb', "id" => "reverb" @@ -271,45 +263,6 @@ public function boot(Panel $panel): void Config::set('filament-alerts.lang', count($this->lang)?$this->lang:[]); Config::set('filament-alerts.types', count($this->types)?$this->types:[]); - if($this->useFCM){ - FilamentView::registerRenderHook( - PanelsRenderHook::BODY_END, - function (){ - return view('filament-alerts::firebase'); - }, - ); - - Notification::macro('sendToFCM', function (Model $user, array $data=[]): static - { - /** @var Notification $this */ - $user->notifyFCMSDK( - title: $this->title, - message: $this->body, - type: 'fcm-web', - url: count($this->actions)? $this->actions[0]->getUrl() : null, - icon: $this->icon, - data: [ - 'url' => count($this->actions)? $this->actions[0]->getUrl() : null, - 'id' => $this->getId(), - 'actions' => array_map(fn (Action | ActionGroup $action): array => $action->toArray(), $this->getActions()), - 'body' => $this->getBody(), - 'color' => $this->getColor(), - 'duration' => $this->getDuration(), - 'icon' => $this->getIcon(), - 'iconColor' => $this->getIconColor(), - 'status' => $this->getStatus(), - 'title' => $this->getTitle(), - 'view' => $this->getView(), - 'viewData' => $this->getViewData(), - 'data'=> $data - ] - ); - - return $this; - }); - } - - if($this->useEmail){ Notification::macro('sendToEmail', function (Model $user): static { @@ -365,6 +318,19 @@ function (){ return $this; }); } + + if($this->useFCM){ + $this->providers = array_merge($this->providers, [ + [ + "name" => 'FCM Web', + "id" => "fcm-web" + ], + [ + "name" => 'FCM Mobile', + "id" => "fcm-api" + ], + ]); + } } public static function make(): static diff --git a/src/FilamentAlertsServiceProvider.php b/src/FilamentAlertsServiceProvider.php index 36c7332..c131247 100644 --- a/src/FilamentAlertsServiceProvider.php +++ b/src/FilamentAlertsServiceProvider.php @@ -25,7 +25,6 @@ public function register(): void //Register generate command $this->commands([ \TomatoPHP\FilamentAlerts\Console\FilamentAlertsInstall::class, - \TomatoPHP\FilamentAlerts\Console\FilamentAlertsFCM::class, ]); //Register Config file @@ -61,9 +60,6 @@ public function register(): void //Register Routes $this->loadRoutesFrom(__DIR__.'/../routes/api.php'); - - Livewire::component(Firebase::class); - } public function boot(): void diff --git a/src/Jobs/NotificationJop.php b/src/Jobs/NotificationJop.php index d2afb55..319ca19 100644 --- a/src/Jobs/NotificationJop.php +++ b/src/Jobs/NotificationJop.php @@ -2,6 +2,8 @@ namespace TomatoPHP\FilamentAlerts\Jobs; +use Filament\Notifications\Actions\Action; +use Filament\Notifications\Actions\ActionGroup; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; @@ -57,13 +59,6 @@ public function __construct($arrgs) */ public function handle() { - if ($this->provider === 'fcm-api' || $this->provider === 'fcm-web') { - $this->user->fcm = $this->provider; - $this->user->fcmId = $this->user->id; - } else { - $this->user->fcm = "fcm-api"; - $this->user->fcmId = $this->user->id; - } if($this->provider === 'sms-misr'){ if($this->user->phone){ @@ -81,6 +76,32 @@ public function handle() Http::post('https://smsmisr.com/api/SMS', $params)->json(); } } + else if ($this->provider === 'fcm-api' || $this->provider === 'fcm-web') { + $this->user->notifyFCMSDK( + message: $this->message, + type: $this->provider, + title: $this->title, + url: $this->url, + image: $this->image, + icon: $this->icon, + data: [ + 'url' => $this->url, + 'id' => $this->model_id, + 'actions' => [], + 'body' => $this->message, + 'color' => null, + 'duration' => null, + 'icon' => $this->icon, + 'iconColor' => null, + 'status' => null, + 'title' => $this->title, + 'view' => null, + 'viewData' => null, + 'data'=> $this->data + ], + sendToDatabase: false + ); + } else { $this->user->notify(new NotificationService( $this->title, diff --git a/src/Jobs/NotifyFCMJob.php b/src/Jobs/NotifyFCMJob.php deleted file mode 100644 index 8743b39..0000000 --- a/src/Jobs/NotifyFCMJob.php +++ /dev/null @@ -1,76 +0,0 @@ -user = $arrgs['user']; - $this->title = $arrgs['title']; - $this->message = $arrgs['message']; - $this->icon = $arrgs['icon']; - $this->url = $arrgs['url']; - $this->image = $arrgs['image']; - $this->type = $arrgs['type']; - $this->data = $arrgs['data']; - } - - /** - * Execute the job. - * - * @return void - */ - public function handle() - { - $this->user->setFCM($this->type)->notify(new FCMNotificationService( - $this->message, - $this->type, - $this->title, - $this->icon, - $this->image, - $this->url, - $this->data, - )); - - $log = new NotificationsLogs(); - $log->title = $this->title; - $log->description = $this->message; - $log->model_id= $this->user->id; - $log->model_type = get_class($this->user); - $log->provider = "fcm"; - $log->type = "info"; - $log->save(); - } -} diff --git a/src/Livewire/Firebase.php b/src/Livewire/Firebase.php deleted file mode 100644 index 4167c5a..0000000 --- a/src/Livewire/Firebase.php +++ /dev/null @@ -1,67 +0,0 @@ -user()){ - $user = auth()->user(); - $user->setFCM('fcm-web')->userTokensFcm()->firstOrCreate([ - 'provider' => 'fcm-web', - 'provider_token' => $token - ]); - } - } - - #[On('fcm-notification')] - public function fcmNotification(mixed $data) - { - $actions = []; - if(isset($data['data'])){ - if(isset($data['data']['actions']) && is_object(json_decode($data['data']['actions']))){ - foreach (json_decode($data['data']['actions']) as $action){ - $actions[] = Action::make($action->name) - ->color($action->color) - ->eventData($action->eventData) - ->icon($action->icon) - ->iconPosition($action->iconPosition) - ->iconSize($action->iconSize) - ->outlined($action->isOutlined) - ->disabled($action->isDisabled) - ->label($action->label) - ->url($action->url) - ->close($action->shouldClose) - ->size($action->size) - ->tooltip($action->tooltip) - ->view($action->view) - ->markAsUnread($action->shouldMarkAsUnRead??false) - ->markAsRead($action->shouldMarkAsRead??false); - } - } - } - - Notification::make($data['data']['id']) - ->title($data['data']['title']) - ->actions($actions) - ->body($data['data']['body']) - ->icon($data['data']['icon']) - ->iconColor($data['data']['iconColor']) - ->color($data['data']['color']) - ->duration($data['data']['duration']) - ->send() - ->sendToDatabase(auth()->user()); - } - - public function render() - { - return view('filament-alerts::firebase-base'); - } -} diff --git a/src/Notifications/FCMNotificationService.php b/src/Notifications/FCMNotificationService.php deleted file mode 100644 index 0a0f44d..0000000 --- a/src/Notifications/FCMNotificationService.php +++ /dev/null @@ -1,84 +0,0 @@ -title, - body: $this->message, - image: $this->image ?? null - ), - data: [ - 'id' => $this->data['id'], - 'actions' => json_encode($this->data['actions']), - 'body' => $this->data['body'], - 'color' => $this->data['color'], - 'duration' => $this->data['duration'], - 'icon' => $this->data['icon'], - 'iconColor' => $this->data['iconColor'], - 'status' => $this->data['status'], - 'title' => $this->data['title'], - 'view' => $this->data['view'], - 'viewData' => json_encode($this->data['viewData']), - 'data' => json_encode($this->data['data']) - ], - custom: [ - 'android' => [ - 'notification' => [ - 'color' => '#0A0A0A', - ], - 'fcm_options' => [ - 'analytics_label' => 'analytics', - ], - ], - 'apns' => [ - 'fcm_options' => [ - 'analytics_label' => 'analytics', - ], - ], - ] - ) - ); - } -} diff --git a/src/Notifications/NotificationService.php b/src/Notifications/NotificationService.php index c5b4ff1..04f31e8 100644 --- a/src/Notifications/NotificationService.php +++ b/src/Notifications/NotificationService.php @@ -84,10 +84,6 @@ public function __construct( */ public function via(mixed $notifiable): array { - if ($this->provider === 'fcm-api' || $this->provider === 'fcm-web') { - return [FcmChannel::class]; - } - if ($this->provider === 'pusher-api' || $this->provider === 'pusher-web') { return [PusherChannel::class]; } @@ -122,68 +118,6 @@ public function toMessagebird($notifiable): MessagebirdMessage return (new MessagebirdMessage($this->message))->setRecipients($this->phone); } - public function toFcm($notifiable): FcmMessage - { - $data = []; - if(is_array($this->data)){ - $data = [ - 'id' => $this->data['id']??null, - 'actions' => $this->data['actions']?json_encode($this->data['actions']):null, - 'body' => $this->message, - 'color' => $this->data['color']??null, - 'duration' => $this->data['duration']??null, - 'icon' => $this->icon, - 'iconColor' => $this->data['iconColor']??null, - 'status' => $this->data['status']??null, - 'title' => $this->title, - 'view' => $this->data['view']??null, - 'viewData' => $this->data['viewData']?json_encode($this->data['viewData']):null, - 'data' => $this->data['data']?json_encode($this->data['data']):null - ]; - } - else { - $data = [ - 'id' => null, - 'actions' => null, - 'body' => $this->message, - 'color' => null, - 'duration' => null, - 'icon' => $this->icon, - 'iconColor' => null, - 'status' => null, - 'title' => $this->title, - 'view' => null, - 'viewData' => null, - 'data' => null - ]; - } - return ( - new FcmMessage( - notification: new FcmNotification( - title: $this->title, - body: $this->message, - image: $this->image ?? null - ), - data: $data, - custom: [ - 'android' => [ - 'notification' => [ - 'color' => '#0A0A0A', - ], - 'fcm_options' => [ - 'analytics_label' => 'analytics', - ], - ], - 'apns' => [ - 'fcm_options' => [ - 'analytics_label' => 'analytics', - ], - ], - ] - ) - ); - } - public function toPushNotification($notifiable): PusherMessage { return PusherMessage::create() diff --git a/src/Traits/InteractsWithNotifications.php b/src/Traits/InteractsWithNotifications.php index 5cbc4a6..d1a6e3b 100644 --- a/src/Traits/InteractsWithNotifications.php +++ b/src/Traits/InteractsWithNotifications.php @@ -19,10 +19,6 @@ trait InteractsWithNotifications { - - protected ?string $fcm; - protected ?int $fcmId; - public function notifySMSMisr( string $message ): void @@ -96,28 +92,6 @@ public function notifyDiscord( ])); } - public function notifyFCMSDK( - string $message, - string $type='web', - ?string $title=null, - ?string $url=null, - ?string $image=null, - ?string $icon=null, - ?array $data=[] - ) - { - dispatch(new NotifyFCMJob([ - 'user' => $this, - 'title' => $title, - 'message' => $message, - 'icon' => $icon, - 'image' => $image, - 'url' => $url, - 'type' => $type, - 'data' => $data, - ])); - } - public function notifyPusherSDK( string $token, string $title, @@ -136,56 +110,13 @@ public function notifyPusherSDK( ])); } - public function initializeUseNotifications() - { - $this->appends[] = 'fcm'; - $this->appends[] = 'fcmID'; - } - - public function setFcmAttribute($value) - { - $this->fcm = $value; - } - - public function getFcmAttribute() - { - return 'fcm-web'; - } - - public function setFcmIdAttribute($value) - { - $this->fcmId = $value; - } - - public function getFcmIdAttribute() - { - return $this->id; - } - public function getUserNotifications() { return $this->morphMany(UserNotification::class, 'model'); } - public function setFCM(?string $type='fcm-web'): static - { - $this->fcm = $type; - $this->fcmId = $this->id; - return $this; - } - - public function userTokensFcm() - { - return $this->morphOne(UserToken::class, 'model')->where('provider', $this->fcm); - } - public function userTokensPusher() { return $this->morphOne(UserToken::class, 'model')->where('provider', 'pusher'); } - - public function routeNotificationForFcm() - { - return $this->userTokensFcm ? $this->userTokensFcm->provider_token : ''; - } } diff --git a/stubs/firebase.stub b/stubs/firebase.stub deleted file mode 100644 index 2879a45..0000000 --- a/stubs/firebase.stub +++ /dev/null @@ -1,62 +0,0 @@ -// Give the service worker access to Firebase Messaging. -// Note that you can only use Firebase Messaging here. Other Firebase libraries -// are not available in the service worker. -importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js'); -importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js'); - -try -{ - // Initialize the Firebase app in the service worker by passing in - // your app's Firebase config object. - // https://firebase.google.com/docs/web/setup#config-object - firebase.initializeApp({ - apiKey: "{{ apiKey }}", - authDomain: "{{ authDomain }}", - databaseURL: "{{ databaseURL }}", - projectId: "{{ projectId }}", - storageBucket: "{{ storageBucket }}", - messagingSenderId: "{{ messagingSenderId }}", - appId: "{{ appId }}", - measurementId: "{{ measurementId }}" - }); - - - // Retrieve an instance of Firebase Messaging so that it can handle background - // messages. - const messaging = firebase.messaging(); - - messaging.onBackgroundMessage((payload) => { - // - {{ sound }} - - let options = { - body: "", - icon: "", - image: "", - tag: "alert", - }; - - if(payload.data.body){ - options.body = payload.data.body; - } - - if(payload.data.image){ - options.icon = payload.data.image; - } - - let notification = self.registration.showNotification( - payload.data.title, - options - ); - - if(payload.data.url){ - // link to page on clicking the notification - notification.onclick = (payload) => { - window.open(payload.data.url); - }; - } - }); -} -catch(e) { - console.log(e) -}