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);
// }
반응형