Skip to content

Instantly share code, notes, and snippets.

@pengkong
Last active January 28, 2017 04:25
Show Gist options
  • Save pengkong/952a90b87754d247073e50647be2f2fa to your computer and use it in GitHub Desktop.
Save pengkong/952a90b87754d247073e50647be2f2fa to your computer and use it in GitHub Desktop.
Google FCM/GCM PHP Server Boilerplate
<?php
$registration_ids = [
'You',
'Only'
];
$data = ['title' => 'Live', 'message' => 'Once!'];
$payload = json_encode([
'registration_ids' => $registration_ids,
"data" => $data,
"priority" => "high"
]);
$ch = curl_init('https://fcm.googleapis.com/fcm/send');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: '.strlen($payload),
'Authorization:key='.config('services.google.api_key')
));
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// https://firebase.google.com/docs/cloud-messaging/http-server-ref#interpret-downstream
// Message was processed successfully.
if ($http_code == 200)
{
$response = json_decode($response);
// $response->success - Number of messages that were processed without an error.
// $response->failure - Number of messages that could not be processed.
// $response->canonical_ids - Number of results that contain a canonical registration token.
// $response->results - Array of objects representing the status of the messages processed.
foreach ($response->results as $result)
{
// $result['message_id'] - String specifying a unique ID for each successfully processed message.
// $result['registration_id'] - Optional string specifying the canonical registration token for the client app that the message was processed and sent to. Sender should use this value as the registration token for future requests. Otherwise, the messages might be rejected.
if ($result['message_id'])
{
// TODO: save message_id to database as indication of success
if ($result['registration_id'])
{
// TODO: replace message_id with registration_id in database
}
}
// $result['error'] - String specifying the error that occurred when processing the message for the recipient.
elseif ($result['error'])
{
// If it is Unavailable, you could retry to send it in another request.
if ($result['error'] == 'Unavailable')
{
// TODO: write to log file and perform exponential back-off retry. see: https://developers.google.com/api-client-library/java/google-http-java-client/backoff
}
// Missing Registration Token - Check that the request contains a registration token
elseif ($result['error'] == 'MissingRegistration')
{
// TODO: write to log file.
}
// Invalid Registration Token - Check the format of the registration token you pass to the server. Make sure it matches the registration token the client app receives from registering with Firebase Notifications. Do not truncate or add additional characters.
elseif ($result['error'] == 'InvalidRegistration')
{
// TODO: write to log file.
}
// Unregistered Device - An existing registration token may cease to be valid in a number of scenarios, including: (1) If the client app unregisters with FCM. (2) If the client app is automatically unregistered, which can happen if the user uninstalls the application. (3) If the registration token expires. (4) If the client app is updated but the new version is not configured to receive messages. For all these cases, remove this registration token from the app server and stop using it to send messages.
elseif ($result['error'] == 'NotRegistered')
{
// TODO: delete registration_id in database
}
// Invalid Package Name - Make sure the message was addressed to a registration token whose package name matches the value passed in the request.
elseif ($result['error'] == 'InvalidPackageName')
{
// TODO: write to log file.
}
// Mismatched Sender - A registration token is tied to a certain group of senders. When a client app registers for FCM, it must specify which senders are allowed to send messages. You should use one of those sender IDs when sending messages to the client app. If you switch to a different sender, the existing registration tokens won't work.
elseif ($result['error'] == 'MismatchSenderId')
{
// TODO: write to log file.
}
// Message Too Big - Check that the total size of the payload data included in a message does not exceed FCM limits: 4096 bytes for most messages, or 2048 bytes in the case of messages to topics or notification messages on iOS. This includes both the keys and the values.
elseif ($result['error'] == 'MessageTooBig')
{
// TODO: write to log file.
}
// Invalid Data Key - Check that the payload data does not contain a key (such as from, or gcm, or any value prefixed by google) that is used internally by FCM. Note that some words (such as collapse_key) are also used by FCM but are allowed in the payload, in which case the payload value will be overridden by the FCM value.
elseif ($result['error'] == 'InvalidDataKey')
{
// TODO: write to log file.
}
// Invalid Time to Live - Check that the value used in time_to_live is an integer representing a duration in seconds between 0 and 2,419,200 (4 weeks).
elseif ($result['error'] == 'InvalidTtl')
{
// TODO: write to log file.
}
// Timeout - The server couldn't process the request in time. Retry the same request, but you must: (1) Honor the Retry-After header if it is included in the response from the FCM Connection Server. (2) Implement exponential back-off in your retry mechanism. Senders that cause problems risk being blacklisted.
elseif ($result['error'] == 'Unavailable')
{
// TODO: write to log file and perform exponential back-off retry. see: https://developers.google.com/api-client-library/java/google-http-java-client/backoff
}
// Internal Server Error - The server encountered an error while trying to process the request. You could retry the same request following the requirements listed in "Timeout" (see row above). If the error persists, please report the problem in the android-gcm group.
elseif ($result['error'] == 'InternalServerError')
{
// TODO: write to log file and perform exponential back-off retry. see: https://developers.google.com/api-client-library/java/google-http-java-client/backoff
}
// Device Message Rate Exceeded - The rate of messages to a particular device is too high. Reduce the number of messages sent to this device and do not immediately retry sending to this device.
elseif ($result['error'] == 'DeviceMessageRateExceeded')
{
// TODO: write to log file and perform exponential back-off retry. see: https://developers.google.com/api-client-library/java/google-http-java-client/backoff
}
// Topics Message Rate Exceeded - The rate of messages to subscribers to a particular topic is too high. Reduce the number of messages sent for this topic, and do not immediately retry sending.
elseif ($result['error'] == 'TopicsMessageRateExceeded')
{
// TODO: write to log file and perform exponential back-off retry. see: https://developers.google.com/api-client-library/java/google-http-java-client/backoff
}
}
}
}
// Only applies for JSON requests. Indicates that the request could not be parsed as JSON, or it contained invalid fields (for instance, passing a string where a number was expected). The exact failure reason is described in the response and the problem should be addressed before the request can be retried.
elseif ($http_code == 400)
{
// TODO: write to log file.
}
// The sender account used to send a message couldn't be authenticated. Possible causes are: (1) Authorization header missing or with invalid syntax in HTTP request. (2) Invalid project number sent as key. (3) Key valid but with FCM service disabled. (4) Request originated from a server not whitelisted in the Server key IPs. Check that the token you're sending inside the Authentication header is the correct Server key associated with your project.
elseif ($http_code == 401)
{
// TODO: write to log file.
}
// Errors in the 500-599 range (such as 500 or 503) indicate that there was an internal error in the FCM connection server while trying to process the request, or that the server is temporarily unavailable (for example, because of timeouts). Sender must retry later, honoring any Retry-After header included in the response. Application servers must implement exponential back-off. (e.g. if you waited one second before the first retry, wait at least two second before the next one, then 4 seconds and so on). If you're sending multiple messages, delay each one independently by an additional random amount to avoid issuing a new request for all messages at the same time.
elseif ($http_code >= 500)
{
// TODO: write to log file and perform exponential back-off retry. see: https://developers.google.com/api-client-library/java/google-http-java-client/backoff
}
else
{
// TODO: write to log file - Unexpected response code
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment