Firebase Cloud Messaging (FCM) client.
Sends push notifications to Android devices and web browsers using the FCM v1 API with OAuth2 authentication via Goth.
Configuration
Add to your config:
config :pushx,
fcm_project_id: "my-project-id",
fcm_credentials: {:file, "priv/keys/firebase-service-account.json"}Usage
# Simple notification
PushX.FCM.send(device_token, %{
"notification" => %{
"title" => "Hello",
"body" => "World"
}
})
# Using Message struct
message = PushX.Message.new("Hello", "World")
PushX.FCM.send(device_token, message)
# With custom data
PushX.FCM.send(device_token, notification, data: %{"key" => "value"})Web Push (Chrome, Firefox, Edge)
FCM supports web push using the same API. Web tokens come from the browser's
Firebase Messaging SDK (firebase.messaging().getToken()).
# Web push with click action
PushX.FCM.send(web_token, payload,
webpush: %{
"fcm_options" => %{"link" => "https://example.com/page"}
}
)
# Using web notification helper
payload = PushX.FCM.web_notification("Title", "Body", "https://example.com")
PushX.FCM.send(web_token, payload)
Summary
Functions
Creates a simple notification payload.
Sends a push notification to an Android device with automatic retry.
Sends notifications to multiple devices concurrently.
Sends a data-only message (no visible notification) with automatic retry.
Sends a data-only message without retry.
Sends a push notification without retry.
Sends a web push notification with automatic retry.
Creates a web push notification payload with click action.
Types
Functions
Creates a simple notification payload.
Examples
iex> PushX.FCM.notification("Hello", "World")
%{"title" => "Hello", "body" => "World"}
@spec send(token(), payload(), [option()]) :: {:ok, PushX.Response.t()} | {:error, PushX.Response.t()}
Sends a push notification to an Android device with automatic retry.
Uses exponential backoff for transient failures following Google's best practices. Permanent failures (bad token, invalid argument) are not retried.
Options
:project_id- Firebase project ID (default: from config):data- Custom data payload map:android- Android-specific configuration:apns- APNS configuration (for iOS via FCM):webpush- Web push configuration
Returns
{:ok, %PushX.Response{}}on success{:error, %PushX.Response{}}on failure
@spec send_batch([token()], payload(), [option()]) :: [ {token(), {:ok, PushX.Response.t()} | {:error, PushX.Response.t()}} ]
Sends notifications to multiple devices concurrently.
Options
All standard options plus:
:concurrency- Max concurrent requests (default: 50):timeout- Timeout per request in ms (default: 30_000)
Returns
A list of {token, result} tuples.
@spec send_data(token(), map(), [option()]) :: {:ok, PushX.Response.t()} | {:error, PushX.Response.t()}
Sends a data-only message (no visible notification) with automatic retry.
@spec send_data_once(token(), map(), [option()]) :: {:ok, PushX.Response.t()} | {:error, PushX.Response.t()}
Sends a data-only message without retry.
@spec send_once(token(), payload(), [option()]) :: {:ok, PushX.Response.t()} | {:error, PushX.Response.t()}
Sends a push notification without retry.
Use this when you want to handle retries yourself or for testing.
@spec send_web(token(), String.t(), String.t(), String.t(), keyword()) :: {:ok, PushX.Response.t()} | {:error, PushX.Response.t()}
Sends a web push notification with automatic retry.
Convenience function that combines web_notification/4 with send/3.
Examples
PushX.FCM.send_web(web_token, "Hello", "World", "https://example.com")
# With options
PushX.FCM.send_web(web_token, "Alert", "Check this out",
"https://example.com/page",
icon: "https://example.com/icon.png"
)
Creates a web push notification payload with click action.
This helper creates a notification optimized for web browsers (Chrome, Firefox, Edge).
The link option specifies the URL to open when the notification is clicked.
Arguments
title- Notification titlebody- Notification bodylink- URL to open when clickedopts- Optional keyword list::icon- Icon URL for the notification:image- Large image URL:badge- Badge icon URL (small monochrome icon):tag- Tag for notification grouping:renotify- Whether to alert again for same tag (default: false):require_interaction- Keep notification until user interacts (default: false)
Examples
# Simple web notification
PushX.FCM.web_notification("New Message", "You have a new message", "https://example.com/messages")
# With icon and badge
PushX.FCM.web_notification("Sale!", "50% off today",
"https://shop.com",
icon: "https://shop.com/icon.png",
badge: "https://shop.com/badge.png"
)