Your IP : 216.73.217.77


Current Path : /home/users/unlimited/www/admin.eclassify.codeskitter.site/app/Services/
Upload File :
Current File : /home/users/unlimited/www/admin.eclassify.codeskitter.site/app/Services/NotificationService.php

<?php

namespace App\Services;

use App\Models\Setting;
use App\Models\UserFcmToken;
use Google\Client;
use Google\Exception;
use RuntimeException;
use Illuminate\Support\Facades\Log;
use Throwable;

class NotificationService {
    /**
     * @param array $registrationIDs
     * @param string|null $title
     * @param string|null $message
     * @param string $type
     * @param array $customBodyFields
     * @return string|array|bool
     */
    public static function sendFcmNotification(array $registrationIDs, string|null $title = '', string|null $message = '', string $type = "default", array $customBodyFields = []): string|array|bool {
        try {
            //TODO : Use this from caching
            $project_id = Setting::select('value')->where('name', 'firebase_project_id')->first();
            if (empty($project_id->value)) {
                return [
                    'error'   => true,
                    'message' => 'FCM configurations are not configured.'
                ];
            }

            $project_id = $project_id->value;
            $url = 'https://fcm.googleapis.com/v1/projects/' . $project_id . '/messages:send';

//            $registrationIDs_chunks = array_chunk($registrationIDs, 1000);

            $access_token = self::getAccessToken();
             if ($access_token['error']) {
                return $access_token;
            }
            $result = [];


            $deviceInfo = UserFcmToken::with('user')
            ->select(['platform_type', 'fcm_token'])
            ->whereIn('fcm_token', $registrationIDs)
            ->whereHas('user', function ($q) {
                $q->where('notification', 1);
            })
            ->get();
            // Log::info('Device Info:', $deviceInfo);
            //TODO : Add this process to queue for better performance
            $dataWithTitle = [
                ...$customBodyFields,
                "title" => $title,
                "body"  => $message,
                "type"  => $type,
            ];
            foreach ($registrationIDs as $registrationID) {
                $platform = $deviceInfo->first(function ($q) use ($registrationID) {
                    return $q->fcm_token == $registrationID;
                });
            
                if (!$platform) {
                    continue;
                }
                $data = [
                    "message" => [
                        "token"        => $registrationID,
                        "data"         => self::convertToStringRecursively($dataWithTitle),
                        "apns"         => [
                            "headers" => [
                                "apns-priority" => "10" // Set APNs priority to 10 (high) for immediate delivery
                            ],
                            "payload" => [
                                "aps" => [
                                    "alert" => [
                                        "title" => $title,
                                        "body"  => $message,
                                    ],
                                    "sound" => "default" // Add this line to enable sound on iOS
                                ]
                            ]
                        ]
                    ]
                ];
                if ($platform->platform_type != 'Android') {
                    $data['message']['notification'] = [
                        "title" => $title,
                        "body"  => $message
                    ];
                }

                $encodedData = json_encode($data);
                $headers = [
                    'Authorization: Bearer ' . $access_token['data'],
                    'Content-Type: application/json',
                ];

                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
                curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

                // Disabling SSL Certificate support temporarily
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $encodedData);

                // Execute post
                $result = curl_exec($ch);

                if (!$result) {
                    die('Curl failed: ' . curl_error($ch));
                }
                curl_close($ch);
            }
            return [
                'error'   => false,
                'message' => "Success",
                'data'    => $result
            ];
        } catch (Throwable $th) {
            throw new RuntimeException($th);
        }
    }

    public static function getAccessToken() {
        try {
            $file_name = Setting::select('value')->where('name', 'service_file')->first();
            if (empty($file_name)) {
                return [
                    'error'   => true,
                    'message' => 'FCM Configuration not found'
                ];
            }
            $file_name = $file_name->value;
            $file_path = base_path('public/storage/' . $file_name);

            if (!file_exists($file_path)) {
                return [
                    'error'   => true,
                    'message' => 'FCM Service File not found'
                ];
            }
            $client = new Client();
            $client->setAuthConfig($file_path);
            $client->setScopes(['https://www.googleapis.com/auth/firebase.messaging']);

            return [
                'error'   => false,
                'message' => 'Access Token generated successfully',
                'data'    => $client->fetchAccessTokenWithAssertion()['access_token']
            ];

        } catch (Exception $e) {
            throw new RuntimeException($e);
        }
    }

    public static function convertToStringRecursively($data, &$flattenedArray = []) {
        foreach ($data as $key => $value) {
            if (is_array($value)) {
                self::convertToStringRecursively($value, $flattenedArray);
            } elseif (is_null($value)) {
                $flattenedArray[$key] = '';
            } else {
                $flattenedArray[$key] = (string)$value;
            }
        }
        return $flattenedArray;
    }

}