option('token'); if (empty($token)) { $this->error('--token 옵션은 필수입니다.'); $this->line(''); $this->line('사용법:'); $this->line(' php artisan fcm:test --token=YOUR_FCM_TOKEN'); $this->line(' php artisan fcm:test --token=YOUR_FCM_TOKEN --channel=push_vendor_register --title="신규업체 알림"'); return self::FAILURE; } $channel = $this->option('channel'); $title = $this->option('title'); $body = $this->option('body'); $dataJson = $this->option('data'); // 추가 데이터 파싱 $data = []; if ($dataJson) { $data = json_decode($dataJson, true); if (json_last_error() !== JSON_ERROR_NONE) { $this->error('--data 옵션은 유효한 JSON이어야 합니다.'); return self::FAILURE; } } // 설정 확인 $this->info('FCM 테스트 발송 시작...'); $this->line(''); $this->table( ['항목', '값'], [ ['Project ID', config('fcm.project_id') ?: '(미설정)'], ['Token', substr($token, 0, 30).'...'], ['Channel', $channel], ['Title', $title], ['Body', mb_substr($body, 0, 50).(mb_strlen($body) > 50 ? '...' : '')], ['Data', $data ? json_encode($data, JSON_UNESCAPED_UNICODE) : '(없음)'], ] ); $this->line(''); // Project ID 확인 if (empty(config('fcm.project_id'))) { $this->error('FCM_PROJECT_ID가 설정되지 않았습니다.'); $this->line('.env 파일에 FCM_PROJECT_ID를 설정해주세요.'); return self::FAILURE; } // Service Account 파일 확인 $saPath = config('fcm.service_account_path'); $fullPath = str_starts_with($saPath, '/') ? $saPath : storage_path($saPath); if (! file_exists($fullPath)) { $this->error("Service Account 파일을 찾을 수 없습니다: {$fullPath}"); $this->line('.env 파일에 FCM_SA_PATH를 확인해주세요.'); return self::FAILURE; } $this->info('Service Account 파일 확인됨: '.basename($fullPath)); // FCM 발송 try { $sender = new FcmSender; $response = $sender->sendToToken($token, $title, $body, $channel, $data); $this->line(''); if ($response->success) { $this->info('✅ FCM 발송 성공!'); $this->line("Message ID: {$response->messageId}"); $this->line("Status Code: {$response->statusCode}"); } else { $this->error('❌ FCM 발송 실패'); $this->line("Error: {$response->error}"); $this->line("Status Code: {$response->statusCode}"); if ($response->isInvalidToken()) { $this->warn('토큰이 유효하지 않습니다. 디바이스에서 새 토큰을 발급받아야 합니다.'); } $this->line(''); $this->line('Response:'); $this->line(json_encode($response->rawResponse, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); return self::FAILURE; } } catch (\Exception $e) { $this->error('FCM 발송 중 예외 발생: '.$e->getMessage()); return self::FAILURE; } return self::SUCCESS; } }