Pigeon.LegacyFCM (Pigeon v2.0.0-rc.0) View Source

Pigeon.Adapter for Legacy Firebase Cloud Messaging (FCM) push notifications.

Getting Started

  1. Create a LegacyFCM dispatcher.
# lib/legacy_fcm.ex
defmodule YourApp.LegacyFCM do
  use Pigeon.Dispatcher, otp_app: :your_app
end
  1. (Optional) Add configuration to your config.exs.
# config.exs

config :your_app, YourApp.LegacyFCM,
  adapter: Pigeon.LegacyFCM,
  key: "your_fcm_key_here"
  1. Start your dispatcher on application boot.
defmodule YourApp.Application do
  @moduledoc false

  use Application

  @doc false
  def start(_type, _args) do
    children = [
      YourApp.LegacyFCM
    ]
    opts = [strategy: :one_for_one, name: YourApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

If you skipped step two, include your configuration.

defmodule YourApp.Application do
  @moduledoc false

  use Application

  @doc false
  def start(_type, _args) do
    children = [
      {YourApp.ADM, legacy_fcm_opts()}
    ]
    opts = [strategy: :one_for_one, name: YourApp.Supervisor]
    Supervisor.start_link(children, opts)
  end

  defp legacy_fcm_opts do
    [
      adapter: Pigeon.LegacyFCM, 
      key: "your_fcm_key_here"
    ]
  end
end
  1. Create a notification.
msg = %{"body" => "your message"}
n = Pigeon.LegacyFCM.Notification.new("your device registration ID", msg)
  1. Send the notification.

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.

YourApp.LegacyFCM.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.LegacyFCM.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.LegacyFCM.Notification.new("registration ID", notification, data)

or

Pigeon.LegacyFCM.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{...}}
  1. 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