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