GCM (Android)

Usage

  1. Set your environment variables.

    config :pigeon, :gcm,
      key: "your_gcm_key_here"
  2. Create a notification packet.

    msg = %{ "body" => "your message" }
    n = Pigeon.GCM.Notification.new("your device registration ID", msg)
  3. Send the packet.

    Pigeon.GCM.push(n)

Sending to Multiple Registration IDs

Pass in a list of registration IDs, as many as you want. IDs will automatically be chunked into sets of 1000 before sending the push (as per GCM guidelines).

  msg = %{ "body" => "your message" }
  n = Pigeon.GCM.Notification.new(["first ID", "second ID"], msg)

Notification Struct

When using Pigeon.GCM.Notification.new/2, message_id and updated_registration will always be nil. These keys are set in the response callback. registration_id can either be a single string or a list of strings.

  %Pigeon.GCM.Notification{
      payload: %{},
      message_id: nil,
      registration_id: nil,
      updated_registration_id: nil
  }

Notifications with Custom Data

GCM accepts both notification and data keys in its JSON payload. Set them like so:

  notification = %{ "body" => "your message" }
  data = %{ "key" => "value" }
  Pigeon.GCM.Notification.new("registration ID", notification, data)

or

  Pigeon.GCM.Notification.new("registration ID")
  |> put_notification(%{ "body" => "your message" })
  |> put_data(%{ "key" => "value" })

Handling Push Responses

  1. Pass an optional anonymous function as your second parameter. This function will get called on each registration ID assuming some of them were successful.

    data = %{ message: "your message" }
    n = Pigeon.GCM.Notification.new(data, "device registration ID")
    Pigeon.GCM.push(n, fn(x) -> IO.inspect(x) end)
  2. Reponses return a tuple of either {:ok, notification} or {:error, reason, notification}. You could handle responses like so:

    on_response = fn(x) ->
      case x do
        {:ok, notification} ->
          # Push successful, check to see if the registration ID changed
          if !is_nil(notification.updated_registration_id) do
            # Update the registration ID in the database
          end
        {:error, :invalid_registration, notification} ->
          # Remove the bad ID from the database
        {:error, reason, notification} ->
          # Handle other errors
      end
    end
    
    data = %{ message: "your message" }
    n = Pigeon.GCM.Notification.new(data, "your device token")
    Pigeon.GCM.push(n, on_response)

Notification structs returned as {:ok, notification} will always contain exactly one registration ID for the registration_id key.

For {:error, reason, notification} tuples, this key can be one or many IDs depending on the error. :invalid_registration will return exactly one, whereas :authentication_error and :internal_server_error will return up to 1000 IDs (and the callback called for each failed 1000-chunked request).

Error Responses

Slightly modified from GCM Server Reference

ReasonDescription
:missing_registrationMissing Registration Token
:invalid_registrationInvalid Registration Token
:not_registeredUnregistered Device
:invalid_package_nameInvalid Package Name
:authentication_errorAuthentication Error
:mismatch_sender_idMismatched Sender
:invalid_jsonInvalid JSON
:message_too_bigMessage Too Big
:invalid_data_keyInvalid Data Key
:invalid_ttlInvalid Time to Live
:unavailableTimeout
:internal_server_errorInternal Server Error
:device_message_rate_exceededMessage Rate Exceeded
:topics_message_rate_exceededTopics Message Rate Exceeded
:unknown_errorUnknown Error