Skip to main content

Push Notifications

Push notifications allow your app to reach users instantly on their mobile devices, even when your app isn't open. For inbox integration, push notifications work alongside in-app notifications to provide a complete notification experience.

How Push Notifications Work with Dialect​

  1. Users subscribe to push notifications via your app or notification components
  2. Firebase Cloud Messaging (FCM) handles device token management and delivery
  3. Dialect routes notifications to subscribed users across all their configured channels
  4. Your mobile app receives push notifications and can handle them with custom actions

Prerequisites​

Before implementing push notifications with Dialect:

  1. App Registration: Your app must be registered with Dialect (registration guide)
  2. User Authentication: Users must be authenticated with JWT tokens (authentication guide)
  3. Set up Firebase Cloud Messaging in your application
    • Follow Firebase's documentation to add the Firebase SDK to your app
    • Implement the necessary code to request and receive an FCM token
  4. Implement wallet integration for Solana signature verification
    • Your app must be able to request message signing from the user's wallet

Once these prerequisites are in place, you can proceed with the subscription and notification flows.

Push Subscription Flow​

Once a user is authenticated, you can register their device to receive push notifications. This involves obtaining an FCM token and associating it with the user's wallet address.

Get FCM Token​

Before you can subscribe to push notifications, you need to obtain an FCM token from Firebase:

import messaging from '@react-native-firebase/messaging';

async function getFCMToken() {
try {
// Request permission (iOS)
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;

if (enabled) {
// Get FCM token
const fcmToken = await messaging().getToken();
console.log('FCM Token:', fcmToken);
return fcmToken;
}
} catch (error) {
console.error('Failed to get FCM token:', error);
}
}

For more detailed implementation instructions, visit the Firebase Cloud Messaging documentation for iOS, Android, and Web.

Push Subscription Management​

Subscribe to Push Notifications​

Once you have an FCM token, subscribe the user to push notifications:

async function subscribeToDialectPush(fcmToken: string, jwtToken: string, clientKey: string) {
try {
const response = await fetch('https://alerts-api.dial.to/v2/push/subscribe', {
method: 'POST',
headers: {
'Authorization': `Bearer ${jwtToken}`,
'X-Dialect-Client-Key': clientKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({
fcmToken: fcmToken,
deviceId: 'unique-device-identifier', // Optional but recommended
appId: 'YOUR_APP_ID' // Optional - for app-specific subscriptions
})
});

if (response.ok) {
console.log('Successfully subscribed to push notifications');
} else {
console.error('Failed to subscribe to push notifications');
}
} catch (error) {
console.error('Push subscription error:', error);
}
}

Parameters:

  • fcmToken: Firebase Cloud Messaging token from your mobile app
  • deviceId: (Optional) Unique device identifier for managing devices
  • appId: (Optional) Subscribe to pushes for specific app only

Unsubscribe from Push Notifications​

async function unsubscribeFromDialectPush(fcmToken: string, jwtToken: string, clientKey: string) {
try {
const response = await fetch('https://alerts-api.dial.to/v2/push/unsubscribe', {
method: 'POST',
headers: {
'Authorization': `Bearer ${jwtToken}`,
'X-Dialect-Client-Key': clientKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({
fcmToken: fcmToken,
deviceId: 'unique-device-identifier', // Should match subscription
appId: 'YOUR_APP_ID' // Optional
})
});

if (response.ok) {
console.log('Successfully unsubscribed from push notifications');
}
} catch (error) {
console.error('Push unsubscription error:', error);
}
}

Handling Push Notifications​

Processing Received Notifications​

import messaging from '@react-native-firebase/messaging';
import { useEffect } from 'react';

export function usePushNotifications() {
useEffect(() => {
// Handle notifications when app is in foreground
const unsubscribeForeground = messaging().onMessage(async remoteMessage => {
console.log('Foreground notification:', remoteMessage);

// Show in-app notification or update notification list
handleDialectNotification(remoteMessage);
});

// Handle notifications when app is opened from background
const unsubscribeBackground = messaging().onNotificationOpenedApp(remoteMessage => {
console.log('Background notification opened:', remoteMessage);

// Navigate to specific screen or perform action
handleNotificationAction(remoteMessage);
});

// Handle notifications when app is opened from quit state
messaging()
.getInitialNotification()
.then(remoteMessage => {
if (remoteMessage) {
console.log('App opened from quit state:', remoteMessage);
handleNotificationAction(remoteMessage);
}
});

return () => {
unsubscribeForeground();
unsubscribeBackground();
};
}, []);
}

function handleDialectNotification(remoteMessage: any) {
const { notification, data } = remoteMessage;

// Dialect notifications include:
// - notification.title
// - notification.body
// - notification.image (optional)
// - data.* (custom data from sender)

console.log('Notification title:', notification?.title);
console.log('Notification body:', notification?.body);
console.log('Custom data:', data);

// Update your notification state/context
// addNotificationToInbox(remoteMessage);
}

function handleNotificationAction(remoteMessage: any) {
const { data } = remoteMessage;

// Handle deep linking based on notification data
if (data?.action === 'open_trade') {
// Navigate to trade screen
navigateToTrade(data.tradeId);
} else if (data?.action === 'open_profile') {
// Navigate to profile screen
navigateToProfile(data.userId);
}
}

Push Notification Data Structure​

Dialect push notifications include standard notification content plus custom data:

{
"notification": {
"title": "Trade Executed! 📈",
"body": "Your buy order for 10 SOL has been executed at $142.50",
"image": "https://example.com/notification-image.png"
},
"data": {
"action": "open_trade",
"tradeId": "123",
"amount": "10",
"price": "142.50",
"appId": "your-app-id",
"notificationId": "notification-uuid"
}
}

Advanced Configuration​

App-Specific Push Subscriptions​

Subscribe to push notifications for specific apps only:

// Subscribe to pushes for all apps (default)
await subscribeToDialectPush(fcmToken, jwtToken, clientKey);

// Subscribe to pushes for specific app only
await subscribeToDialectPush(fcmToken, jwtToken, clientKey, deviceId, 'specific-app-id');

Notification Categories and Topics​

Push notifications respect user subscription preferences:

  • Channel subscriptions: Users must be subscribed to apps via channels (IN_APP, EMAIL, etc.)
  • Topic subscriptions: If your app uses topics, push notifications will only be sent for subscribed topics
  • Push preference: Users must specifically enable push notifications

Custom Push Behavior​

Configure push notification behavior:

// Send push notification with custom configuration
const notificationData = {
recipient: {
type: 'subscriber',
walletAddress: 'USER_WALLET_ADDRESS'
},
channels: ['PUSH', 'IN_APP'],
message: {
title: 'Custom Push Notification',
body: 'This includes custom data and actions'
},
push: {
playNotificationSound: true, // Play sound (default: true)
showNotification: true // Show UI notification (default: true)
},
data: {
action: 'custom_action',
deepLink: '/custom-path',
customField: 'custom-value'
}
};

Troubleshooting​

Common Issues​

Push notifications not received:

  • Verify FCM token is valid and current
  • Check if user is subscribed to push notifications via Dialect
  • Ensure app has notification permissions
  • Verify Firebase project configuration

Authentication errors:

  • Ensure JWT token is valid and not expired
  • Verify client key is correct
  • Check if user has proper permissions

iOS-specific issues:

  • Verify APNs certificate is properly configured in Firebase
  • Check iOS notification permissions
  • Ensure app is properly signed for push notifications

Best Practices​

💡 User Experience:

  • Request push permission at the right moment (not immediately on app launch)
  • Clearly explain the value of push notifications
  • Provide easy opt-out options
  • Handle permission denials gracefully

💡 Technical Implementation:

  • Keep FCM tokens updated when they change
  • Handle token refresh properly
  • Implement proper error handling for network failures
  • Use unique device IDs for better device management

Next Steps​

With push notifications integrated, you have a complete notification system:

  1. User Management - Manage user subscriptions and preferences
  2. Notification History - Retrieve and display notification history
  3. Authentication - Handle user authentication flows

Your users can now receive notifications via in-app messages, email, and push notifications across all their devices!