CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-native-firebase--messaging

React Native Firebase integration for Firebase Cloud Messaging (FCM) providing cross-platform push notification capabilities

Pending
Overview
Eval results
Files

topic-management.mddocs/

Topic Management

Topic subscription management for targeted messaging campaigns. Topics allow apps to subscribe to and receive messages sent to specific categories or interests.

Capabilities

Subscribe to Topic

Subscribe the device to a named topic to receive targeted messages sent to that topic.

/**
 * Subscribe device to a topic for targeted messaging
 * @param topic - Topic name (must not contain forward slashes)
 * @returns Promise that resolves when subscription is complete
 */
function subscribeToTopic(topic: string): Promise<void>;

Usage Examples:

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

// Subscribe to news updates
await messaging().subscribeToTopic('news');
console.log('Subscribed to news topic');

// Subscribe to user-specific topics
const userId = getCurrentUserId();
await messaging().subscribeToTopic(`user_${userId}`);

// Subscribe to multiple topics
const topics = ['sports', 'weather', 'breaking-news'];
await Promise.all(
  topics.map(topic => messaging().subscribeToTopic(topic))
);

// Modular API
import { getMessaging, subscribeToTopic } from '@react-native-firebase/messaging';
const messagingInstance = getMessaging();
await subscribeToTopic(messagingInstance, 'news');

Unsubscribe from Topic

Unsubscribe the device from a topic to stop receiving messages sent to that topic.

/**
 * Unsubscribe device from a topic
 * @param topic - Topic name to unsubscribe from
 * @returns Promise that resolves when unsubscription is complete
 */
function unsubscribeFromTopic(topic: string): Promise<void>;

Usage Examples:

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

// Unsubscribe from news updates
await messaging().unsubscribeFromTopic('news');
console.log('Unsubscribed from news topic');

// Unsubscribe when user logs out
const userId = getCurrentUserId();
await messaging().unsubscribeFromTopic(`user_${userId}`);

// Unsubscribe from multiple topics
const topics = ['sports', 'weather'];
await Promise.all(
  topics.map(topic => messaging().unsubscribeFromTopic(topic))
);

// Modular API
import { getMessaging, unsubscribeFromTopic } from '@react-native-firebase/messaging';
const messagingInstance = getMessaging();
await unsubscribeFromTopic(messagingInstance, 'news');

Topic Rules and Limitations

Topic Name Requirements

  • No Forward Slashes: Topic names must not contain / characters
  • Case Sensitive: Topic names are case-sensitive
  • Character Limit: Maximum length varies by platform but typically 900 characters
  • Valid Characters: Alphanumeric characters, hyphens, and underscores recommended

Subscription Limits

  • Per App: Up to 2000 topic subscriptions per app instance
  • Global: No limit on total subscribers to a topic
  • Propagation: Subscriptions may take up to 24 hours to propagate

Error Conditions

Topics with invalid names will throw errors:

// These will throw errors
try {
  await messaging().subscribeToTopic('news/sports'); // Contains forward slash
} catch (error) {
  console.error('Invalid topic name:', error.message);
}

try {
  await messaging().subscribeToTopic(''); // Empty topic name
} catch (error) {
  console.error('Empty topic name:', error.message);
}

Topic Management Patterns

User Preference Topics

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

class TopicManager {
  static async updateUserTopics(preferences: UserPreferences) {
    const messaging = messaging();
    
    // Subscribe to enabled topics
    for (const topic of preferences.enabledTopics) {
      await messaging.subscribeToTopic(topic);
    }
    
    // Unsubscribe from disabled topics
    for (const topic of preferences.disabledTopics) {
      await messaging.unsubscribeFromTopic(topic);
    }
  }
  
  static async subscribeToUserSpecificTopics(userId: string) {
    const messaging = messaging();
    
    // Personal notifications
    await messaging.subscribeToTopic(`user_${userId}`);
    
    // Account-related updates
    await messaging.subscribeToTopic(`account_${userId}`);
  }
  
  static async unsubscribeFromUserTopics(userId: string) {
    const messaging = messaging();
    
    await messaging.unsubscribeFromTopic(`user_${userId}`);
    await messaging.unsubscribeFromTopic(`account_${userId}`);
  }
}

// Usage
await TopicManager.subscribeToUserSpecificTopics('user123');
await TopicManager.updateUserTopics({
  enabledTopics: ['news', 'sports'],
  disabledTopics: ['weather', 'politics']
});

Geographic Topics

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

class LocationTopicManager {
  static async updateLocationTopics(
    oldLocation: string | null, 
    newLocation: string
  ) {
    const messaging = messaging();
    
    // Unsubscribe from old location
    if (oldLocation) {
      await messaging.unsubscribeFromTopic(`location_${oldLocation}`);
      await messaging.unsubscribeFromTopic(`weather_${oldLocation}`);
    }
    
    // Subscribe to new location
    await messaging.subscribeToTopic(`location_${newLocation}`);
    await messaging.subscribeToTopic(`weather_${newLocation}`);
  }
}

// Usage
await LocationTopicManager.updateLocationTopics('new-york', 'san-francisco');

App Version Topics

import messaging from '@react-native-firebase/messaging';
import { getVersion } from 'react-native-device-info';

class VersionTopicManager {
  static async subscribeToVersionTopics() {
    const messaging = messaging();
    const version = await getVersion();
    
    // Subscribe to version-specific updates
    await messaging.subscribeToTopic(`version_${version.replace(/\./g, '_')}`);
    
    // Subscribe to major version updates
    const majorVersion = version.split('.')[0];
    await messaging.subscribeToTopic(`major_version_${majorVersion}`);
  }
}

// Usage
await VersionTopicManager.subscribeToVersionTopics();

Server-Side Topic Messaging

Topics are managed server-side through Firebase Admin SDK or HTTP API:

Admin SDK Example (Node.js)

// Server-side code (not React Native)
import admin from 'firebase-admin';

// Send to topic
const message = {
  notification: {
    title: 'Breaking News',
    body: 'Important update for all news subscribers',
  },
  topic: 'news'
};

await admin.messaging().send(message);

// Send to multiple topics
const multiTopicMessage = {
  notification: {
    title: 'Weather Alert',
    body: 'Severe weather warning',
  },
  condition: "'weather' in topics && 'severe-alerts' in topics"
};

await admin.messaging().send(multiTopicMessage);

Best Practices

  1. Descriptive Names: Use clear, descriptive topic names
  2. Hierarchical Structure: Consider using prefixes for organization (news_sports, news_politics)
  3. User Control: Always provide users control over topic subscriptions
  4. Cleanup: Unsubscribe from user-specific topics on logout
  5. Error Handling: Handle network errors during subscription/unsubscription
  6. Batch Operations: Use Promise.all() for multiple topic operations
  7. Topic Limits: Monitor subscription count to stay within limits

Topic Subscription Management

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

class TopicSubscriptionManager {
  private static subscriptions = new Set<string>();
  
  static async subscribe(topic: string): Promise<boolean> {
    try {
      await messaging().subscribeToTopic(topic);
      this.subscriptions.add(topic);
      console.log(`Subscribed to topic: ${topic}`);
      return true;
    } catch (error) {
      console.error(`Failed to subscribe to ${topic}:`, error);
      return false;
    }
  }
  
  static async unsubscribe(topic: string): Promise<boolean> {
    try {
      await messaging().unsubscribeFromTopic(topic);
      this.subscriptions.delete(topic);
      console.log(`Unsubscribed from topic: ${topic}`);
      return true;
    } catch (error) {
      console.error(`Failed to unsubscribe from ${topic}:`, error);
      return false;
    }
  }
  
  static getSubscriptions(): string[] {
    return Array.from(this.subscriptions);
  }
  
  static async unsubscribeAll(): Promise<void> {
    const unsubscribePromises = Array.from(this.subscriptions).map(
      topic => this.unsubscribe(topic)
    );
    await Promise.all(unsubscribePromises);
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-react-native-firebase--messaging

docs

android-features.md

index.md

ios-features.md

message-handling.md

permissions-registration.md

token-management.md

topic-management.md

tile.json