# Zend_Mobile_Push_C2dm

`Zend_Mobile_Push_C2dm` 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_C2dm`.

## Pushing Messages

Prior to pushing messages; you must sign up for a c2dm account. In order to get your application to recieve push notifications, you should follow: Writing Android Applications that Use C2DM.

When implementing C2DM; you have a few components that you will utilize. `Zend_Mobile_Push_C2dm` which contains the server components and `Zend_Mobile_Push_Message_C2dm` which contains the message that you would like to send. 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.

    try {
        $client = Zend_Gdata_ClientLogin::getHttpClient(
            'my@gmail.com', // REPLACE WITH YOUR GOOGLE ACCOUNT
            'myPassword', // REPLACE WITH YOUR PASSWORD
            Zend_Mobile_Push_C2dm::AUTH_SERVICE_NAME,
            null,
            'myAppName' // REPLACE WITH YOUR APP NAME
        );
    } catch (Zend_Gdata_App_CaptchaRequiredException $cre) {
        // manual login is required
        echo 'URL of CAPTCHA image: ' . $cre->getCaptchaUrl() . PHP_EOL;
        echo 'Token ID: ' . $cre->getCaptchaToken() . PHP_EOL;
        exit(1);
    } catch (Zend_Gdata_App_AuthException $ae) {
        echo 'Problem authenticating: ' . $ae->exception() . PHP_EOL;
        exit(1);
    }

    $message = new Zend_Mobile_Push_Message_C2dm();
    $message->setId(time());
    $message->setToken('ABCDEF0123456789');
    $message->setData(array(
        'foo' => 'bar',
        'bar' => 'foo',
    ));

    $c2dm = new Zend_Mobile_Push_C2dm();
    $c2dm->setLoginToken($client->getClientLoginToken());

    try {
        $c2dm->send($message);
    } catch (Zend_Mobile_Push_Exception_InvalidToken $e) {
        // you would likely want to remove the token from being sent to again
        echo $e->getMessage();
    } catch (Zend_Mobile_Push_Exception $e) {
        // all other exceptions only require action to be sent or implementation of exponential backoff.
        echo $e->getMessage();
    }

### 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 C2DM when there was an unknown exception or internally on input validation. | Read the message and determine remediation steps.
Zend_Mobile_Push_Exception_InvalidPayload | Generally the payload will not throw an exception unless the size of the payload is too large or it is missing required content. | Check the size of the payload is within the requirements of C2DM
Zend_Mobile_Push_Exception_InvalidToken | Any form of an invalid token will be if the token is no longer registered; you are missing a token or it is in an invalid format. | You should remove the token and not attempt to send to it again.
Zend_Mobile_Push_Exception_InvalidTopic | An invalid topic simply means that the message id was too long or not an integer. | Ensure that the message ID is an integer.
Zend_Mobile_Push_Exception_DeviceQuotaExceeded | You have sent too many messages to this device; you may retry again later. | Grab the HTTP client and check to see if there was a retry-after header; otherwise implement Exponential Backoff
Zend_Mobile_Push_Exception_QuotaExceeded | You have sent too many messages and have gone over the quota for the day; you may try again later. | Grab the HTTP client and check to see if there was a retry-after header; like above implement Exponential Backoff. Secondly; if you are continually going over your limit; you may request Request a higher quota. See the link on the bottom of the page.

## Advanced Messages

C2DM 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_C2dm` 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_C2dm();
        $message->setDelayWhileIdle(true);