Reputation: 1
Keep receiving 403 when trying to send FCM notification from a PHP script with Google API Client for PHP 7.4 library installed
Warning: file_get_contents(https://fcm.googleapis.com/v1/projects//messages:send): failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden in file_get_contents()
My code is
require_once libraries_get_path('google-api-php-client') . '/vendor/autoload.php';
$client = new Google_Client();
try {
$client->setAuthConfig(libraries_get_path('google-api-php-client') .
'/....json');
$client->addScope(Google_Service_FirebaseCloudMessaging::CLOUD_PLATFORM);
// $accessToken = generateToken($client);
$client->fetchAccessTokenWithAssertion();
$accessToken = $client->getAccessToken();
$client->setAccessToken($accessToken);
$oauthToken = $accessToken["access_token"];
$device_token = '...';
$payload = ["message" => ["token" => $device_token, "notification"=>["title" => 'test message', "body"=> 'message body']]];
$postdata = json_encode($payload);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-Type: application/json' . "\r\nAuthorization: Bearer $oauthToken",
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents('https://fcm.googleapis.com/v1/projects/<project>/messages:send', false, $context);
where service_account.json contains
{
"type": "service_account",
"project_id": "",
"private_key_id": "...",
"private_key": "...",
"client_email": "...iam.gserviceaccount.com",
"client_id": "...",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/...iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}
I"m dealing with a legacy Drupal 7.x site so bumping PHP up to 8 is not an option. Sofar my suspicion is that the Google API PHP 7.4 library is the problem.
Any ideas/suggestions will be highly appreciated.
Upvotes: 0
Views: 59
Reputation: 11
for sending through google you must use authentication method. which means that you must acquire key.json first from firebase console
it should be contain like this
{
"type": "",
"project_id": "",
"private_key_id": "",
"private_key": "",
"client_email": "",
"client_id": "",
"auth_uri": "",
"token_uri": "",
"auth_provider_x509_cert_url": "",
"client_x509_cert_url": "",
"universe_domain": "",
}
then you should use require google library. im using this
composer require google/apiclient
require that on your project like this
require APPPATH . '/libraries/php-google/autoload.php';
use Google\Auth\Credentials\ServiceAccountCredentials;
on my example, i create a function to create a authentication
function getAccessToken() {
$key = json_decode(file_get_contents('/config/key.json'), true);
$scopes = ['https://www.googleapis.com/auth/cloud-platform']; // Define the scopes you need
$credentials = new ServiceAccountCredentials($scopes, [
'client_email' => $key['client_email'],
'private_key' => $key['private_key']
]);
return $credentials->fetchAuthToken()['access_token'];
}
change '/config/key.json' to the path of your key.. best to dont put it on public folder.
here is for send notification function
<?php
function send_notification ($token,$title,$body,$link=null) {
$fcmUrl = "https://fcm.googleapis.com/v1/projects/YOUR PROJECT NAME/messages:send";
$args = func_get_args();
$response = ["status" => 0, "message" => "Notification couldn't be sent"];
$tokenArr = $token;
$msgNotification = [
"title" => $title,
"body" => $body,
];
$extraNotificationData = [
"notification_id" => "",
"title" => $title,
"link" => $link
];
$fcmNotification = [
"message" => [
"token" => $tokenArr,
"notification" => $msgNotification,
"android" => [
"priority" => "normal"
],
"data" => $extraNotificationData
]
];
$headers = [
"Authorization: Bearer ".getAccessToken(),
"Content-Type: application/json"
];
if ($token == null || $token == '') {
$result = '';
}
else {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$fcmUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $encodedData);
$result = curl_exec($ch);
if ($result === FALSE) {
$result = curl_error($ch);
}
curl_close($ch);
}
$response = ["status" => 1, "message" => "Notification sent to users", "payload" => $result];
return [$response,$token];
}
?>
Upvotes: 0