mob_notify

Local and push notifications for apps built with Mob — the device half of Mob.Notify, extracted from mob core as a plugin. Owns scheduling, cancellation, and push registration; pairs with the server-side mob_push package for sending.

Installation

# mix.exs
{:mob_notify, "~> 0.1"}
# mob.exs
config :mob, :plugins, [:mob_notify]

Requires the :notifications permission (Mob.Permissions.request(socket, :notifications)). Android 13+'s POST_NOTIFICATIONS and the firebase-messaging gradle dep are merged from this plugin's manifest; iOS needs no plist key.

Usage

Local notifications:

MobNotify.schedule(socket,
id: "reminder_1",
title: "Time to check in",
body: "Open the app to see today's updates",
at: ~U[2026-04-16 09:00:00Z], # or delay_seconds: 60
data: %{screen: "reminders"}
)
MobNotify.cancel(socket, "reminder_1")
def handle_info({:notification, %{id: id, data: data, source: :local}}, socket), do: ...

Push registration (call once after :notifications is granted):

socket = MobNotify.register_push(socket)
def handle_info({:push_token, platform, token}, socket) do
# platform is :ios | :android — store both, send with MobPush.send/3 server-side
end
def handle_info({:notification, %{title: t, body: b, data: d, source: :push}}, socket), do: ...

Notifications arrive via handle_info regardless of app state — foreground, background, or relaunched after being killed. Delivery plumbing lives in mob core; this plugin is the API surface.

Host app requirements

Four manual steps the build can't automate. mob_new-generated apps already satisfy all of them via their templates; hand-rolled hosts must add:

  1. Android — FCM service: AndroidManifest.xml must declare <service android:name=".MobFirebaseService" android:exported="false"> with the com.google.firebase.MESSAGING_EVENT intent filter. The MobFirebaseService.kt class ships in the host app, not this plugin (FirebaseMessagingService subclasses must live in the host package).
  2. Android — Firebase wiring: the host build.gradle needs the com.google.gms.google-services plugin + a google-services.json from the Firebase console (buildscript classpath entries are host-level).
  3. iOS — APNs token forwarding: the host AppDelegate must call mob_send_push_token(hex) (exported by mob core) in didRegisterForRemoteNotificationsWithDeviceToken.
  4. Android — display receiver: scheduled notifications display via a <applicationId>.NotificationReceiver BroadcastReceiver declared in AndroidManifest.xml — this plugin only arms the alarm.

Limits

Development

Clone, then run once:

mix setup

That fetches deps and activates the repo's git hooks (.githooks/pre-push): mix format --check, mix credo --strict (incl. ExSlop), and mix compile --warnings-as-errors run on every push, plus the full test suite when mix.exs changes — the same gate CI enforces before publishing.

License

MIT