Skip to content

Instantly share code, notes, and snippets.

@SametSahin10
Created March 4, 2025 23:20
Show Gist options
  • Save SametSahin10/dbbd1020d80ff5c1d66b110786a85e59 to your computer and use it in GitHub Desktop.
Save SametSahin10/dbbd1020d80ff5c1d66b110786a85e59 to your computer and use it in GitHub Desktop.
<?php
/**
* Gets an access token for FCM API calls
* @param string $serviceAccountPath Path to your service account JSON file
* @return string The access token
*/
function getAccessToken($serviceAccountPath) {
$serviceAccount = json_decode(file_get_contents($serviceAccountPath), true);
// Create JWT
$now = time();
$jwt = [
'iss' => $serviceAccount['client_email'],
'scope' => 'https://www.googleapis.com/auth/firebase.messaging',
'aud' => 'https://oauth2.googleapis.com/token',
'exp' => $now + 3600,
'iat' => $now
];
// Encode JWT Header
$jwtHeader = base64_encode(json_encode(['alg' => 'RS256', 'typ' => 'JWT']));
$jwtHeader = str_replace(['+', '/', '='], ['-', '_', ''], $jwtHeader);
// Encode JWT Payload
$jwtPayload = base64_encode(json_encode($jwt));
$jwtPayload = str_replace(['+', '/', '='], ['-', '_', ''], $jwtPayload);
// Create JWT Signature
$jwtSignature = $jwtHeader . '.' . $jwtPayload;
$key = $serviceAccount['private_key'];
openssl_sign($jwtSignature, $signature, $key, 'SHA256');
$jwtSignature = base64_encode($signature);
$jwtSignature = str_replace(['+', '/', '='], ['-', '_', ''], $jwtSignature);
// Create signed JWT
$signedJwt = $jwtHeader . '.' . $jwtPayload . '.' . $jwtSignature;
// Exchange JWT for access token
$ch = curl_init('https://oauth2.googleapis.com/token');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $signedJwt
]));
$response = curl_exec($ch);
curl_close($ch);
$token = json_decode($response, true);
return $token['access_token'];
}
/**
* Sends an FCM message to a topic using the HTTP v1 API
* @param string $serviceAccountPath Path to your service account JSON file
* @param string $projectId Your Firebase project ID
* @param string $topic The FCM topic to send to (without the /topics/ prefix)
* @param array $data Optional data payload
* @return array The response from FCM
*/
function sendFCMMessageToTopic($serviceAccountPath, $projectId, $topic, $data = []) {
$url = "https://fcm.googleapis.com/v1/projects/{$projectId}/messages:send";
// Get access token from service account
$accessToken = getAccessToken($serviceAccountPath);
$message = [
'message' => [
'topic' => $topic,
'data' => $data,
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($message));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"Authorization: Bearer {$accessToken}"
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 200 && $httpCode < 300) {
echo "Successfully sent message to topic: " . $response . PHP_EOL;
return json_decode($response, true);
} else {
echo "Error sending message to topic: " . $response . PHP_EOL;
throw new Exception("FCM Error: " . $response);
}
}
/**
* Main function to demonstrate usage
*/
function main() {
$serviceAccountPath = ''; // Path to your service account JSON file
$projectId = ''; // Your Firebase project ID
$topic = ''; // Topic name without /topics/ prefix
$data = ['mail' => '', 'number' => ''];
try {
sendFCMMessageToTopic($serviceAccountPath, $projectId, $topic, $data);
echo "Message sent successfully" . PHP_EOL;
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . PHP_EOL;
}
}
// Run the main function
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment