Skip to main content

Firebase Cloud Messaging Setup

FCM

Configure Firebase Cloud Messaging (FCM) to send push notifications to Android and web browsers.

Cross-Platform

Android, Web, iOS support

Free Tier

Generous free message quota

Rich Messages

Images, actions, data payloads

Analytics

Delivery and engagement stats

Firebase Project Setup

Create and configure a Firebase project for push notifications:

1

Create Firebase Project

Go to the Firebase Console and click Add project. Follow the wizard to create your project.

2

Enable Cloud Messaging

In your project settings, navigate to Cloud Messaging tab. Enable the Firebase Cloud Messaging API if prompted.

3

Add Your App

Click Add app and select your platform (Web, Android, or iOS). Follow the setup instructions to register your app.

4

Get Configuration

Copy your Firebase configuration object. You'll need this for client-side integration.

Firebase Config
// Your Firebase configuration (from Firebase Console)
const firebaseConfig = {
  apiKey: "AIzaSy...",
  authDomain: "your-app.firebaseapp.com",
  projectId: "your-app",
  storageBucket: "your-app.appspot.com",
  messagingSenderId: "123456789",
  appId: "1:123456789:web:abc123",
}

Service Account Configuration

Generate a service account key for server-side push notifications:

1

Open Service Accounts

In Firebase Console, go to Project Settings → Service accounts.

2

Generate Private Key

Click Generate new private key. A JSON file will download containing your credentials.

3

Store Securely

Never commit this file to version control. Store it securely and reference via environment variables.

Security Warning

Your service account key grants full access to Firebase services. Never expose it in client-side code or commit it to repositories.
.env.local
# Option 1: Path to service account file
FIREBASE_SERVICE_ACCOUNT_PATH=/path/to/service-account.json

# Option 2: Inline JSON (escape quotes)
FIREBASE_SERVICE_ACCOUNT='{"type":"service_account","project_id":"..."}'

# Option 3: Individual credentials
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_CLIENT_EMAIL=firebase-adminsdk@your-project.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"

Adding FCM to Console

Configure FCM credentials in the Sylphx dashboard:

1

Navigate to Settings

Go to App Settings → Notifications → Push Providers.

2

Add FCM Provider

Click Add Provider and select Firebase Cloud Messaging.

3

Upload Credentials

Upload your service account JSON file or paste the JSON contents directly.

4

Test Connection

Click Test Connection to verify your credentials are valid.

SDK Configuration
import { platform } from '@/lib/platform'

// FCM is automatically configured once added in the dashboard
// No additional SDK configuration needed

// Verify FCM is configured
const providers = await platform.notifications.getProviders()
console.log(providers.fcm) // { enabled: true, projectId: '...' }

Sending Push via FCM

Send push notifications through FCM using the SDK:

Server-side
import { platform } from '@/lib/platform'

// Send to a specific user (uses their registered FCM token)
await platform.notifications.send({
  userId: user.id,
  title: 'New message',
  body: 'You have a new message from Sarah',
  icon: '/icon-192.png',
  data: {
    url: '/messages/123',
    messageId: '123',
  },
})

// Send to specific FCM token directly
await platform.notifications.sendToToken({
  token: 'fcm-device-token...',
  title: 'Order Update',
  body: 'Your order has shipped!',
  data: {
    orderId: '456',
  },
})

// Send to multiple tokens
await platform.notifications.sendToTokens({
  tokens: ['token1...', 'token2...', 'token3...'],
  title: 'Flash Sale!',
  body: '50% off for the next 2 hours',
})
Send to Topic
// Subscribe users to topics
await platform.notifications.subscribeToTopic({
  tokens: [user1Token, user2Token],
  topic: 'promotions',
})

// Send to all topic subscribers
await platform.notifications.sendToTopic({
  topic: 'promotions',
  title: 'Weekend Sale',
  body: 'Save 30% on all items this weekend!',
  data: {
    saleId: 'weekend-2024',
  },
})

FCM Message Format

Understanding the FCM message structure:

await platform.notifications.send({
  userId: user.id,

  // Notification payload (shown to user)
  title: 'Order Shipped!',
  body: 'Your order #123 is on its way.',
  icon: '/icons/shipping.png',
  image: '/images/package.jpg', // Large image
  badge: '/icons/badge.png',

  // Click action
  clickAction: 'https://myapp.com/orders/123',

  // Android-specific options
  android: {
    channelId: 'orders',
    priority: 'high',
    ttl: 3600, // Seconds until message expires
    collapseKey: 'order-updates',
    notification: {
      color: '#4F46E5',
      sound: 'default',
      tag: 'order-123', // Replaces existing with same tag
    },
  },

  // Web-specific options
  webpush: {
    headers: {
      TTL: '3600',
      Urgency: 'high',
    },
    fcmOptions: {
      link: '/orders/123',
    },
  },

  // Custom data payload
  data: {
    orderId: '123',
    status: 'shipped',
    trackingUrl: 'https://tracking.example.com/123',
  },
})

Message Properties

PropertyTypeDescription
titlerequiredstringNotification title
bodyrequiredstringNotification body text
iconstringSmall icon URL
imagestringLarge image URL for expanded view
badgestringBadge icon (Android)
clickActionstringURL to open on click
dataobjectCustom key-value data
androidobjectAndroid-specific options
webpushobjectWeb push-specific options
apnsobjectiOS-specific options (when using FCM for iOS)

Android Channel Options

PropertyTypeDescription
channelIdstringNotification channel ID (required for Android 8+)
priority"high" | "normal"= "normal"Message priority
ttlnumberTime-to-live in seconds
collapseKeystringKey for collapsing multiple messages
soundstring= "default"Sound to play
colorstringNotification accent color (hex)
tagstringTag for replacing existing notifications

Troubleshooting FCM

Common issues and solutions:

Invalid registration token

Cause: Token expired or was never valid

Solution: Request a new token from the client and update your database

MismatchSenderId

Cause: Token was generated for a different Firebase project

Solution: Ensure client and server use the same Firebase project credentials

NotRegistered

Cause: App was uninstalled or token was invalidated

Solution: Remove the invalid token from your database

MessageTooBig

Cause: Payload exceeds 4KB limit

Solution: Reduce data payload size or use data-only messages

QuotaExceeded

Cause: Too many messages sent in short time

Solution: Implement rate limiting and batch messages

Handle Token Errors
import { platform } from '@/lib/platform'

// Listen for token errors
platform.notifications.onTokenError(async (error) => {
  if (error.code === 'messaging/invalid-registration-token' ||
      error.code === 'messaging/registration-token-not-registered') {
    // Remove invalid token from database
    await db.pushTokens.delete({
      where: { token: error.token },
    })
  }
})

// Validate tokens before sending
const result = await platform.notifications.validateTokens({
  tokens: ['token1...', 'token2...'],
})

console.log(result)
// {
//   valid: ['token1...'],
//   invalid: ['token2...'],
// }

Debug Mode

Enable debug logging in development to see detailed FCM request/response information:SYLPHX_DEBUG=notifications node server.js