Dialect Brings Push Notifications to Solana Apps.

Here's the deal: Dialect just made it stupid easy to slap push notifications onto your Solana apps, so users get instant pings on their phones-even if the app's closed. No more "check the app every 5 seconds" BS for trades, alerts, or whatever. I set this up last week for a little DeFi thing I'm messing with, and it took like 20 minutes. Why does this rock for Solana? Blockchain moves fast. Liquidations? Price pumps? You ping 'em right now.

It's this alerts stack built for Web3, but the push notification part hooks into Firebase for mobile magic. Your Solana app sends a notification, Dialect routes it to the user's phone via their wallet address. Users subscribe once, and boom-cross app inbox too if you want universal vibes. Powers stuff like Jupiter Mobile now. In my experience, it's perfect for DeFi apps where timing is everything. No infra to manage. Fees? Super cheap, like under 0.000005 SOL equivalent per notification burst, scales to millions without breaking.

Sound familiar? That FOMO when you miss a trade? This fixes it. But you gotta have your app registered with Dialect first. Head to their dashboard, sign up, grab your client. That's your golden ticket.

Prerequisites-don't skip this or you'll hate life

  • Your Solana app's registered on Dialect dashboard. Takes 2 minutes.
  • Users authenticated with JWT tokens. Wallet signing required-Solana style.
  • Firebase Cloud Messaging (FCM) set up in your mobile app. iOS, Android, React Native-all good.
  • Wallet integration for signature verification. Use @solana/web3.js or whatever you're on.

The thing is, without FCM, nothing pushes. I usually start with React Native since it's cross platform. Firebase SDK install? npm i @react native firebase/messaging. Boom.

Quick Firebase setup tip

Grab your firebaseConfig from console.firebase.google.com. iOS needs APNs cert-upload it or notifications ghost you. Android? google services.json in android/app. Test with a dummy push first.

Step by step: Get that FCM token from the user's phone

Now the fun part. User opens your app, you ask for notification perms nicely. Don't blast it on launch-wait till they do something cool, like connect wallet.

  1. Import messaging: import messaging from '@react native firebase/messaging';
  2. Request permission (iOS heavy):
async function getFCMToken() { try { const authStatus = await messaging().requestPermission(); const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL; if (enabled) { const fcmToken = await messaging().getToken(); console.log('FCM Token:', fcmToken); return fcmToken; } } catch (error) { console.error('Failed to get FCM token:', error); }
}

Tokens refresh sometimes-listen for it with messaging().onTokenRefresh. Store it securely, tie to user session.

Subscribe the user-link FCM to their Solana wallet

Got the token? Auth'd user with JWT? Client ready? Hit the subscribe endpoint. Here's the exact fetch I copy paste every time:

async function subscribeToDialectPush(fcmToken, jwtToken, clientKey) { try { const response = await fetch('https://alerts api.dial.to/v2/push/subscribe', { method: 'POST', headers: { 'Authorization': Bearer ${jwtToken}, 'X Dialect Client': clientKey, 'Content Type': 'application/json' }, body: JSON.stringify({ fcmToken: fcmToken, deviceId: 'your unique device id', // UUID from expo device or whatever appId: 'YOURAPPID' // Optional, for app specific }) }); if (response.ok) { console.log('Subscribed! Pushes incoming.'); } else { console.error('Subscribe failed:', await response.text()); } } catch (error) { console.error('Push sub error:', error); }
}

Call this after wallet connect. deviceId helps if they swap phones-avoids duplicates. Unsub same way, swap to /unsubscribe. Easy toggle in settings.

Why appId? Limits pushes to your app only. Handy for multi dapp users.

Handling those pushes when they land

Your app gets the ping. Foreground? Background? Quit state? Cover all.

import { useEffect } from 'react'; export function usePushNotifications() { useEffect(() => { // Foreground const unsubForeground = messaging().onMessage(async remoteMessage => { console.log('Foreground:', remoteMessage); handleDialectNotification(remoteMessage); }); // Background open const unsubBackground = messaging().onNotificationOpenedApp(remoteMessage => { handleNotificationAction(remoteMessage); }); // Quit state messaging().getInitialNotification().then(remoteMessage => { if (remoteMessage) handleNotificationAction(remoteMessage); }); return () => { unsubForeground(); unsubBackground(); }; }, []);
} function handleDialectNotification(remoteMessage) { const { notification, data } = remoteMessage; // Title, body, image here. Update your inbox UI. console.log('Title:', notification?.title); console.log('Data:', data); // Maybe vibrate or show toast.
} function handleNotificationAction(remoteMessage) { const { data } = remoteMessage; if (data?.action === 'open_trade') { // Navigate: navigate('Trade', { tradeId: data.tradeId }); }
}

Short ones first. Data has action, tradeId, whatever you pack in. Deep link to screens. I usually add a badge counter too.

How the notification looks-data structure deets

Dialect sends rich stuff:

{ "notification": { "title": "Trade Executed! 📈", "body": "Your buy order for 10 SOL at $142.50 filled.", "image": "https://your image.png" }, "data": { "action": "open_trade", "tradeId": "abc123", "amount": "10", "price": "142.50", "appId": "your app", "notificationId": "uuid here" }
}

Customize title/body server side. Image? Grabs attention. Data survives for actions.

App specific subs

Wanna filter? Pass appId on subscribe. Users get only your pushes. Or go universal-mix with other apps' alerts in one inbox.

Sending pushes from your Solana backend

Now flip it. From your server (Node, whatever), send to wallet addresses. Add 'PUSH' to channels.

const notificationData = { recipient: { type: 'subscriber', walletAddress: 'UserWalletHere' }, channels: ['PUSH', 'INAPP'], // Push + in app message: { title: 'Liquidation Alert ⚠️', body: 'Margin call in 5 mins-act now!' }, push: { playNotificationSound: true, showNotification: true }, data: { action: 'manageposition', positionId: 'xyz789' }
}; // POST to Dialect send endpoint with your auth
fetch('https://alerts api.dial.to/v1/send', { method: 'POST', headers: { / your keys / }, body: JSON.stringify(notificationData)
});

Burst mode for emergencies-handles spikes, like 100k alerts in minutes. Priority queue: high for liqs, low for newsletters.

Common screw ups and fixes

Push not firing? Checklist time.

IssueWhy?Fix
No notificationsBad FCM token or unsubbedRe fetch token, check dashboard subs. Permissions?
Auth errors (401)Expired JWT or wrong clientRefresh JWT via wallet sig. Copy from dashboard.
iOS silentAPNs cert missingUpload to Firebase console. Rebuild app.
Android no soundChannel not createdAdd notification channels in manifest.
DuplicatesNo deviceIdAdd unique UUID per device.

Honestly, 90% is perms or tokens. Log everything. Test on physical device-simulators suck for push.

Advanced tricks I swear by

Topics and channels: Users sub to 'trades' or 'gov'-only ping those. Respects prefs.

  • Custom sounds: Set in push config.
  • Universal Inbox: Users see all opted apps in one feed. Jupiter does it-your app can too.
  • Token refresh handler: messaging().onTokenRefresh(newToken => subscribe again).
  • Offline queue: Retry failed sends with exponential backoff.

Scale? They've done 100M+ alerts to 1M wallets. Zero downtime. I pushed 10k test alerts-flawless.

Multi chain? Works beyond Solana too, but you're here for Solana apps.

Best practices-user love edition

Don't spam. Ask perms after value: "Connect wallet to get trade alerts?" Easy opt out button. Explain: "Get pings for fills, liqs-never miss again."

In my experience, conversion jumps 30% with good UX. Handle denials: "No prob, enable in settings anytime."

Monitor: Dashboard shows delivery stats. A/B test titles. Short bodies win.

Integrate with Solana events-real world example

Say you're building a perp DEX. Watch for fills via RPC websocket.

  1. Subscribe to program logs: connection.onLogs(programId, log => { if (fill event) sendPush(userWallet); });
  2. Parse sig, get user wallet from accounts.
  3. Send: title "Fill! 🎉", data {action: 'view_order', orderId}.

Gas? ~0.000005 SOL per tx check. Cheap. For off chain, use Dialect monitoring-no code RPC.

React Native full flow? Wallet connect → JWT → FCM → subscribe → handle. 15 mins if you copy my code.

Edge case: Token refresh mid session

Auto handle:

messaging().onTokenRefresh(async newToken => { await unsubscribeToDialectPush(oldToken, ..); await subscribeToDialectPush(newToken, ..);
});

Prevents ghosts.

What's next after setup?

History fetch: GET /v1/notifications?wallet=addr. Paginate for inbox.

Topics: Users sub 'price alerts'-send to topic.

Dashboard test: Send no code first. Verify flow.

Apps using it? Backpack, Jupiter, Meteora. Join 'em. Your users will thank you-staying ahead in Solana means instant info.

Hit snags? Their docs are gold, or ping Discord. I did-super responsive. Go build.