FCM (Android)

Usage

  1. Set your environment variables.

     config :pigeon, :fcm,
       fcm_default: %{
         key: "your_fcm_key_here"
       }
  2. Create a notification packet.

     msg = %{"body" => "your message"}
     n = Pigeon.FCM.Notification.new("your device registration ID", msg)
  3. Send the packet. Pushes are synchronous and return the notification with updated :status and :response keys. If :status is success, :response will contain a keyword list of individual registration ID responses.

     Pigeon.FCM.push(n)

Sending to Multiple Registration IDs

Pass in a list of registration IDs, as many as you want.

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

Notification Struct

  %Pigeon.FCM.Notification{
    collapse_key: nil | String.t(),
    dry_run: boolean,
    message_id: nil | String.t(),
    payload: %{...},
    priority: :normal | :high,
    registration_id: String.t() | [String.t(), ...],
    response: [] | [{atom, String.t()}, ...], | atom,
    restricted_package_name: nil | String.t(),
    status: atom | nil,
    time_to_live: non_neg_integer
  }

Notifications with Custom Data

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

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

or

  Pigeon.FCM.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.

     data = %{message: "your message"}
     n = Pigeon.FCM.Notification.new(data, "device registration ID")
     Pigeon.FCM.push(n, fn(x) -> IO.inspect(x) end)
     {:ok, %Pigeon.FCM.Notification{...}}
  2. Reponses return the notification with an updated response.

     on_response = fn(n) ->
       case n.status do
         :success ->
           bad_regids = FCM.Notification.remove?(n)
           to_retry = FCM.Notification.retry?(n)
           # Handle updated regids, remove bad ones, etc
         :unauthorized ->
           # Bad FCM key
         error ->
           # Some other error
       end
     end
     
     data = %{message: "your message"}
     n = Pigeon.FCM.Notification.new("your device token", data)
     Pigeon.FCM.push(n, on_response: on_response)

Error Responses

Slightly modified from FCM 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