프로그램 개발서

PHP 5.4.16 버전에서 FCM HTTP V1 푸시 알림 보내는 방법!! 본문

PHP

PHP 5.4.16 버전에서 FCM HTTP V1 푸시 알림 보내는 방법!!

rairen 2024. 9. 9. 16:51

 

PHP 버전이 5.4인데 푸시 알림을 보내려면 http v1 으로 마이그레이션을 해야하는 상황!

 

하지만 인터넷 검색하면 초반에 나오는 내용은 php7나 8등의 상위버전 내용이라서 원하는 내용을 찾을 수 없었다.

 

여러가지를 알아보다 내가 사용한 방법으로 php-jwt를 이용한 방법이다.

 

1. 깃 허브 파이어베이스 레포지터리 중 php-jwt를 들어가서 자신의버전에 맞는 버전을 찾아 다운받는다.

나의 경우 php 5.4.16 버전에서 사용가능한 버전이 필요한 상황

릴리즈를 확인해보니

6.1버전부터 PHP >= 7.1이상만 지원하고 그 밑으로는 지원이 중단된 상황!

따라서 6.0.0 버전을 다운로드!

GitHub - firebase/php-jwt: PHP package for JWT

 

 

2. 다운로드 jwt를 압출풀고 서버에 업로드한다.

 

3. 푸시 발송할 php 파일에서 설정 값을 정의하자!

define("API_LIB_PATH", $_SERVER["DOCUMENT_ROOT"] . "/api/lib");
define("JWT_PATH" , API_LIB_PATH . "/php-jwt/php-jwt-6.0.0"); // PHP-JWT

define("GOOGLE_CLOUD_PROJECT_ID", "");// 구글 클라우드에서 사용할 프로젝트 아이디 입력!!!!
define("FIREBASE_CLOUD_MESSAGING_URL", "https://fcm.googleapis.com/v1/projects/" . GOOGLE_CLOUD_PROJECT_ID . "/messages:send");

define("API_KEY_PATH", $_SERVER["DOCUMENT_ROOT"] . "/api/key");
define("API_KEY_FILE_NAME", "");// 서버에 업로드한 파이버에시스 비공개 키 파일!!!!
define("FIREBASE_PRIVATE_KEY_FILE_PATH", API_KEY_PATH . "/" . API_KEY_FILE_NAME);

 

GOOGLE_CLOUD_PROJECT_ID 와  API_KEY_FILE_NAME 값만 넣어주면 된다.

 

4. JWT 라이브러리 로드!

// JWT 라이브러리 경로를 명시적으로 포함
require_once JWT_PATH .'/src/JWT.php';
require_once JWT_PATH .'/src/ExpiredException.php';
require_once JWT_PATH .'/src/SignatureInvalidException.php';
require_once JWT_PATH .'/src/BeforeValidException.php';

use \Firebase\JWT\JWT;

 

 

5. JWT 생성함수 작성

// JWT 생성
function createJWT($serviceAccountKey) {
    $now_seconds = time();
    
    // Firebase 서비스 계정의 client_email 및 private_key 가져오기
    $clientEmail = $serviceAccountKey['client_email'];
    $privateKey = $serviceAccountKey['private_key'];
    
    // JWT payload 생성
    $payload = array(
        "iss" => $clientEmail, // 서비스 계정의 이메일
        "sub" => $clientEmail, // 서비스 계정의 이메일
        "aud" => "https://oauth2.googleapis.com/token",
        "iat" => $now_seconds, // 발급 시간
        "exp" => $now_seconds + (60 * 60), // 만료 시간 (1시간)
        "scope" => "https://www.googleapis.com/auth/firebase.messaging" // FCM API에 대한 권한
    );
    
    // JWT 생성 (RS256 알고리즘 사용)
    return JWT::encode($payload, $privateKey, 'RS256');
}

 

 

 

6. JWT 를 사용한 엑세스 토큰 얻기

 

// JWT를 사용하여 액세스 토큰 가져오기
function getAccessToken($jwt) {
    // 구글 OAuth 토큰 요청 URL
    $url = "https://oauth2.googleapis.com/token";
    
    // POST 요청에 사용할 데이터
    $data = http_build_query(array(
        'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
        'assertion' => $jwt,
    ));
    
    // cURL 초기화
    $ch = curl_init();
    
    // cURL 옵션 설정
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    
    // 요청 실행
    $result = curl_exec($ch);
    
    if ($result === FALSE) {
        die('Error: ' . curl_error($ch));
    }
    
    curl_close($ch);
    
    // JSON 응답을 배열로 디코드
    $responseData = json_decode($result, true);
    
    // 액세스 토큰 반환
    return $responseData['access_token'];
}

 

 

7. FCM 푸시 알림 발송  함수 작성!

function sendFCM($accessToken, $deviceToken, $title, $body, $imageUrl = null) {
	// 파이어베이스 클라우드 메시지 주소
    $url = FIREBASE_CLOUD_MESSAGING_URL;
    
    // HTTP v1 요청에 사용될 헤더
    $headers = array(
        'Authorization: Bearer ' . $accessToken,
        'Content-Type: application/json',
    );
	// 토픽으로 멀티캐시트 발송 시 token이 아닌 topic으로 처리하면 됨.
    // 공통 알림 데이터
    $message = [
        "token" => $deviceToken,
        "notification" => [
            "title" => $title,
            "body" => $body,
            "image" => $imageUrl
        ],
        "android" => [
            "priority" => "high",
            "notification" => [
                "sound" => "default",
                "click_action" => "OPEN_ACTIVITY_1"
            ]
        ],
        "apns" => [
            "headers" => [
                "apns-priority" => "10",  // 즉시 전송
            ],
            "payload" => [
                "aps" => [
                    "alert" => [
                        "title" => $title,
                        "body" => $body
                    ],
                    "sound" => "default"  // iOS 알림 소리 설정
                ]
            ]
        ]
    ];

    // 데이터 필드 (선택 사항)
	
    $message["data"] = [
            "title" => $title,
            "body" => $body,
            "image" => $imageUrl
    ];
	
	
    // 메시지 요청 데이터
    $postData = json_encode([
        "message" => $message
    ]);
	
    // cURL 초기화
    $ch = curl_init();
    
    // cURL 옵션 설정
    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_POSTFIELDS, $postData);
    
    // 요청 실행
    $result = curl_exec($ch);

    // 에러 발생 여부 확인
    if ($result === FALSE) {
        die('FCM Send Error: ' . curl_error($ch));
    }

    // 요청 종료
    curl_close($ch);
    
    return $result;
}

 

 

8. 서비스 비공개 파일로 JWT 생성하고 토큰을 얻어보자!

// 서비스 계정 JSON 파일 로드
$serviceAccountKey = json_decode(file_get_contents(FIREBASE_PRIVATE_KEY_FILE_PATH), true);

// JWT 생성
$jwt = createJWT($serviceAccountKey);

// 액세스 토큰 가져오기
$accessToken = getAccessToken($jwt);// 서버가 Firebase API에 요청을 보내기 위해 사용하는 토큰

 

9. 발송 시행 (단일 / 멀티) 방법

 

// 단일
// $response = sendFCM($accessToken, $deviceToken, $title, $body, $imageUrl);

// 멀티 (토픽 사용하지 안을 때)
// for(){
// $response = sendFCM($accessToken, $deviceToken, $title, $body, $imageUrl);
// }

 

반응형

'PHP' 카테고리의 다른 글

PHP Byte 단위 표시용 함수  (0) 2025.03.13
[CI4] 카페24에 설치 해보기  (0) 2023.12.30
[phpDocumentor]@todo  (0) 2023.12.06
[phpDocumentor]@version  (0) 2023.12.06
[phpDocumentor]@abstract  (0) 2023.12.06