Push notifications
Transactional and campaign push across FCM, APNs and Web Push — with tags, segments, localization, rich media, action buttons and A/B tests.
Push has two halves:
- Devices register their token — automatically, with the Flutter SDK — tied to the person's identity, language and tags.
- Sends come from the console (campaigns, automations, A/B tests, schedules) or from your backend (transactional sends to users, segments or filters).
1. Configure providers
In the console under Push → Settings, add credentials once per environment:
| Provider | Credential |
|---|---|
| FCM (Android, and iOS via Firebase) | A Firebase service-account JSON |
| APNs (iOS, required for Live Activities and VoIP) | The .p8 key, Key ID, Team ID, bundle id. Save & test checks it against Apple in sandbox and production. |
| Web Push | A VAPID key pair (the console can generate one) |
2. Register devices (Flutter)
await Nexus.init(const NexusConfig(apiKey: 'nxs_live_xxx', pushEnabled: true));That is the whole integration. The SDK asks for permission, gets the token, registers it for the current person, re-registers on refresh, shows notifications while the app is in the foreground (with its own native code — no extra packages), and reports opens.
App prerequisites (the standard Firebase setup):
- Android —
google-services.json, and apply the Google Services Gradle plugin (id("com.google.gms.google-services")) inandroid/app/build.gradle(.kts). - iOS —
GoogleService-Info.plist; enable Push Notifications and Background Modes → Remote notifications; upload the APNs key to Firebase. - Web — initialise Firebase yourself and pass
pushWebVapidKey.
const NexusConfig(apiKey: '…', pushEnabled: true, pushAutoRequestPermission: false);
// … at the right moment, after your own explainer screen:
await Nexus.instance.push.start();iOS renders custom buttons and images only through a Notification Service Extension — a one-time step Apple requires of every SDK:
- Xcode → File → New → Target → Notification Service Extension (iOS 12+).
- Replace its
NotificationService.swiftwith the SDK'sios/NexusNotificationServiceExtension/NexusNotificationService.swift. - Build. Nexus already sends
mutable-content: 1and the button definitions.
await Nexus.instance.push.registerToken(token, platform: PushPlatform.android);
// raw APNs token: provider: PushProvider.apns
Nexus.instance.push.reportOpen(message.data);
await Nexus.instance.push.unregister(); // on sign-outLanguage, tags and opens
final push = Nexus.instance.push;
await push.setLanguage('ar'); // campaigns arrive in this language
await push.setTag('role', 'client'); // target with segments
await push.setTags({'plan': 'pro', 'city': 'erbil'});
await push.removeTag('city');
push.onOpened = (open) {
// open.campaignId, open.actionId (button), open.actionUrl, open.data
if (open.actionUrl != null) launchUrl(Uri.parse(open.actionUrl!));
};Localization falls back from en-US to en, then to the campaign's default
language, then to the base message.
3. Send from your backend
$nexus->push()->notification()
->title('Your order shipped')
->body('Track it in the app')
->image('https://cdn.example.com/box.png')
->data(['screen' => '/orders/42'])
->button('track', 'Track', ['url' => 'https://example.com/track'])
->iosBadge(1)
->toUser('user_1')
->send(); // ['sent' => …, 'failed' => …, 'recipients' => …]
$nexus->push()->sendToUser('user_1', ['title' => 'Welcome 👋']);Laravel notifications: return a NexusPushMessage from toNexusPush() — see
the PHP SDK.
Targeting
Targets combine as a union:
| Builder | Reaches |
|---|---|
toUser(id) / toUsers([…]) | every device registered for those distinct ids |
setSegments([…]) / toSegments([…]) | saved segments (built in Push → Segments from tags, platform, language, …) |
where({platform: 'ios', lang: 'en'}) | an ad-hoc device filter, tags included |
toAll() / ToEveryone() | every device (overrides the rest) |
Per-platform options
| Option | Platform |
|---|---|
button(id, label, {url}) — up to 3 | all |
iosBadge, iosSubtitle, iosRelevanceScore, iosInterruptionLevel | iOS |
androidVisibility, androidLargeIcon, androidBigPicture, androidAccentColor | Android |
option(key, value) / options({…}) | anything newer (web icon/image/badge, small icon…) |
Sends are never retried automatically
A timeout does not tell you whether a notification went out, and a duplicate is
worse than a miss. A steady non-zero failed usually means stale tokens or
expired provider credentials.
Campaigns & automations
In the console, Push composes campaigns with a live preview, translations (Localize), rich options, scheduling and A/B variants, and reports delivery and open rates. Automations send when a product event is tracked. Open rates count campaign sends only — API and automation sends have no open attribution.
Reference
Realtime
Environment-scoped pub/sub rooms over Socket.IO — emit from servers over HTTP, listen from apps, with optional payload schemas.
In-app messages
Designed modals, bottom sheets, banners, full-screen takeovers and carousels — targeted, personalised and A/B-tested on the server, drawn natively by the SDK.
