Token validation for push notification device tokens.
Validates token format before sending to avoid unnecessary API calls. Validation is fast (microseconds) and catches obvious errors early.
APNS Tokens (iOS/macOS/Safari)
APNS device tokens are 64 hexadecimal characters (32 bytes).
Safari web push tokens use the same format.
Example: "a1b2c3d4e5f6...64 hex chars total"
FCM Tokens (Android/Web)
FCM registration tokens are variable length:
- Mobile tokens: typically 140-250 characters
- Web tokens: typically 50-200 characters
They contain alphanumeric characters, hyphens, underscores, and colons.
Example:
"dGVzdC10b2tlbi1mb3ItZmNt..."
Usage
iex> PushX.Token.valid?(:apns, "a1b2c3d4" <> String.duplicate("0", 56))
true
iex> PushX.Token.valid?(:apns, "too-short")
false
iex> PushX.Token.validate(:apns, "invalid")
{:error, :invalid_format}
Summary
Functions
Returns a human-readable error message for validation errors.
Returns true if the token is valid for the given provider.
Validates a device token and returns :ok or {:error, reason}.
Validates a token and raises ArgumentError if invalid.
Types
@type provider() :: :apns | :fcm
@type token() :: String.t()
@type validation_error() :: :empty | :invalid_format | :invalid_length
Functions
@spec error_message(provider(), validation_error()) :: String.t()
Returns a human-readable error message for validation errors.
Returns true if the token is valid for the given provider.
Examples
iex> PushX.Token.valid?(:apns, String.duplicate("a", 64))
true
iex> PushX.Token.valid?(:apns, "invalid")
false
@spec validate(provider(), token()) :: :ok | {:error, validation_error()}
Validates a device token and returns :ok or {:error, reason}.
Examples
iex> PushX.Token.validate(:apns, String.duplicate("a", 64))
:ok
iex> PushX.Token.validate(:apns, "")
{:error, :empty}
iex> PushX.Token.validate(:apns, "too-short")
{:error, :invalid_length}
iex> PushX.Token.validate(:apns, String.duplicate("g", 64))
{:error, :invalid_format}
Validates a token and raises ArgumentError if invalid.
Examples
iex> PushX.Token.validate!(:apns, String.duplicate("a", 64))
:ok
iex> PushX.Token.validate!(:apns, "invalid")
** (ArgumentError) Invalid APNS token: invalid_length