# Zend_Mobile_Push_Gcm

`Zend_Mobile_Push_Gcm` provides the ability to send push notifications to Android devices that contain Google Services. A message will always be constructed with `Zend_Mobile_Push_Message_Gcm`.

## Pushing Messages

Prior to pushing and receiving messages; you will need to create a Google API Project and setup your Android app to listen to GCM messages.. If you have not done this, follow the GCM: Getting Started document.

When implementing GCM; you have a few components that you will utilize. `Zend_Mobile_Push_Gcm` which contains the server components, `Zend_Mobile_Push_Message_Gcm` which contains the message that you would like to send, and `Zend_Mobile_Push_Response_Gcm` which contains the response from GCM. Each message sent must do an HTTP request; so remember this when sending in large batches.

The actual implementation of the code is fairly minimal; however, considerations to error handling must be taken.

    $message = new Zend_Mobile_Push_Message_Gcm();
    $message->addToken('ABCDEF0123456789');
    $message->setData(array(
        'foo' => 'bar',
        'bar' => 'foo',
    ));

    $gcm = new Zend_Mobile_Push_Gcm();
    $gcm->setApiKey('YOUR_API_KEY');

    try {
        $response = $gcm->send($message);
    } catch (Zend_Mobile_Push_Exception $e) {
        // exceptions require action or implementation of exponential backoff.
        die($e->getMessage());
    }

    // handle all errors and registration_id's
    foreach ($response->getResults() as $k => $v) {
        if ($v['registration_id']) {
            printf("%s has a new registration id of: %s\r\n", $k, $v['registration_id']);
        }
        if ($v['error']) {
            printf("%s had an error of: %s\r\n", $k, $v['error']);
        }
        if ($v['message_id']) {
            printf("%s was successfully sent the message, message id is: %s", $k, $v['message_id']);
        }
    }

### Exceptions and Remediation Techniques

Exception | Meaning | Handling
--- | --- | ---
Zend_Mobile_Push_Exception | These types of exceptions are more generic in nature and are thrown either from gcm when there was an unknown exception or internally on input validation. | Read the message and determine remediation steps.
Zend_Mobile_Push_Exception_InvalidAuthToken | Your API key was likely typed in wrong or does not have rights to the GCM service. | Check your project on the Google APIs Console page.
Zend_Mobile_Push_Exception_ServerUnavailable | This exception means there was either an internal server error OR that the server denied your request and you should look at the Retry-After header. | Read the exception message and utilize Exponential Backoff
Zend_Mobile_Push_Exception_InvalidPayload | Generally the payload will not throw an exception unless the size of the payload is too large or the JSON is too large. | Check the size of the payload is within the requirements of GCM, currently it is 4K.

## Advanced Messages

GCM provides the ability for sending more advanced messages; for instance the examples above show the most basic implementation of a message. `Zend_Mobile_Push_Message_Gcm` allows you to do far more advanced messaging outlined below.

### Delay While Idle

If included, indicates that the message should not be sent immediately if the device is idle. The server will wait for the device to become active, and then only the last message for each collapse_key value will be sent.

        $message = new Zend_Mobile_Push_Message_Gcm();
        $message->setDelayWhileIdle(true);

### Time to Live

You may set the time to live in seconds, by default GCM will save it for 4 weeks. Additionally if you specify a Time to Live, you must also set an ID (the collapse key). Generally it is best by using the message data so that you know it is a unique message.

        $message = new Zend_Mobile_Push_Message_Gcm();
        $message->setTtl(86400);
        $message->addData('key', 'value');
        $message->setId(md5(json_encode($message->getData())));

## Response

GCM gives a response back that contains detail that needs to be understood. Most of the time you can just send a message but the server may come back telling you any the message id, any errors and potentially new registration ids.

### Results

The results are most commonly retrieved by calling the getResults() method. However, you may prefer to just get certain results by using the getResult() method. The getResult method utilizes the constants RESULT_* correlating to message id, error or registration id.

Several utility methods exist to give you a better idea of what happened during your send. Methods getSuccessCount(), getFailureCount() and getCanonicalCount() let you know how many where successful, how many failures and how many updates to registration ids you have.