CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-node-gcm

Easy interface for Google's Cloud Messaging service (now Firebase Cloud Messaging)

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

sender.mddocs/

Message Sending

Message delivery system with FCM authentication, automatic retries, and comprehensive error handling for reliable push notification delivery. The Sender handles authentication, request formatting, response parsing, and retry logic.

Capabilities

Sender Constructor

Creates a new Sender instance with FCM server API key and optional configuration.

/**
 * Creates a new Sender instance
 * @param {string} apiKey - FCM server API key
 * @param {Object} options - Optional sender configuration
 * @returns {Sender} Sender instance
 */
function Sender(apiKey, options);

// Can be called with or without 'new'
const sender1 = new Sender('YOUR_API_KEY');
const sender2 = Sender('YOUR_API_KEY', { timeout: 30000 });

Usage Examples:

const gcm = require('node-gcm');

// Basic sender
const sender = new gcm.Sender('AIzaSyD...YOUR_FCM_SERVER_KEY');

// Sender with custom options
const sender = new gcm.Sender('AIzaSyD...YOUR_FCM_SERVER_KEY', {
    timeout: 60000,  // Custom timeout
    proxy: 'http://proxy.example.com:8080'  // HTTP proxy
});

Send with Automatic Retries

Sends a message with automatic retry logic for failed deliveries.

/**
 * Send message with automatic retries and custom options
 * @param {Message} message - Message instance to send
 * @param {Recipient} recipient - Target recipient(s)
 * @param {SendOptions|number} options - Send options or retry count
 * @param {Function} callback - Callback function (err, response)
 */
sender.send(message, recipient, options, callback);

/**
 * Send message with automatic retries using default options
 * @param {Message} message - Message instance to send
 * @param {Recipient} recipient - Target recipient(s)
 * @param {Function} callback - Callback function (err, response)
 */
sender.send(message, recipient, callback);

/**
 * Send message with specific retry count
 * @param {Message} message - Message instance to send
 * @param {Recipient} recipient - Target recipient(s)
 * @param {number} retries - Number of retry attempts
 * @param {Function} callback - Callback function (err, response)
 */
sender.send(message, recipient, retries, callback);

Usage Examples:

const message = new gcm.Message({ data: { alert: 'Hello World' } });
const tokens = ['token1', 'token2', 'token3'];

// Send with default retry settings (5 retries)
sender.send(message, { registrationTokens: tokens }, function(err, response) {
    if (err) {
        console.error('Send failed:', err);
    } else {
        console.log('Send successful:', response);
        // Handle failed tokens
        const failedTokens = tokens.filter((token, i) => 
            response.results[i].error === 'NotRegistered'
        );
        console.log('Failed tokens to remove:', failedTokens);
    }
});

// Send with custom retry options
sender.send(message, { registrationTokens: tokens }, {
    retries: 3,
    backoff: 2000  // 2 second initial backoff
}, function(err, response) {
    console.log('Send completed');
});

// Send with specific retry count
sender.send(message, { registrationTokens: tokens }, 10, function(err, response) {
    console.log('Send with 10 retries completed');
});

Send without Retries

Sends a message once without any retry logic.

/**
 * Send message without automatic retries
 * @param {Message} message - Message instance to send
 * @param {Recipient} recipient - Target recipient(s)
 * @param {Function} callback - Callback function (err, response)
 */
sender.sendNoRetry(message, recipient, callback);

Usage Example:

const message = new gcm.Message({ 
    notification: { title: 'Test', body: 'Test message' } 
});

sender.sendNoRetry(message, 'single_token_here', function(err, response) {
    if (err) {
        console.error('Send failed (no retries):', err);
    } else {
        console.log('Send successful:', response);
    }
});

Recipient Types

Different ways to specify message recipients.

Single Registration Token

// Send to a single device
const recipient = 'eHcE7r_bNzE:APA91bF...'; // Registration token string
sender.send(message, recipient, callback);

Multiple Registration Tokens

// Send to multiple devices (array format)
const recipients = ['token1', 'token2', 'token3']; // Max 1000 tokens
sender.send(message, recipients, callback);

// Send to multiple devices (object format)
const recipients = {
    registrationTokens: ['token1', 'token2', 'token3']
};
sender.send(message, recipients, callback);

// Deprecated format (still supported)
const recipients = {
    registrationIds: ['token1', 'token2', 'token3']
};
sender.send(message, recipients, callback);

Topic Messaging

// Send to a topic
const recipient = { topic: 'news' };
sender.send(message, recipient, callback);

// Alternative format
const recipient = '/topics/news';
sender.send(message, recipient, callback);

Condition-based Messaging

// Send based on topic conditions
const recipient = {
    condition: "'sports' in topics && 'news' in topics"
};
sender.send(message, recipient, callback);

Device Group Messaging

// Send to device group (notification key)
const recipient = {
    notificationKey: 'APA91bH...' // Device group key
};
sender.send(message, recipient, callback);

Send Options

Configuration options for controlling retry behavior.

interface SendOptions {
    /** Number of retry attempts (default: 5) */
    retries?: number;
    
    /** Initial backoff delay in milliseconds (default: 1000) */
    backoff?: number;
}

Usage Examples:

// Custom retry configuration
const options = {
    retries: 10,        // Retry up to 10 times
    backoff: 500        // Start with 500ms delay
};

sender.send(message, recipients, options, callback);

// Quick shorthand for just retry count
sender.send(message, recipients, 3, callback); // 3 retries

Response Handling

Understanding FCM response structure for processing results.

Success Response

interface FCMResponse {
    /** Unique identifier for the multicast message */
    multicast_id?: number;
    
    /** Number of successful deliveries */
    success: number;
    
    /** Number of failed deliveries */
    failure: number;
    
    /** Number of registration token updates */
    canonical_ids: number;
    
    /** Array of individual message results (matches recipient order) */
    results: MessageResult[];
}

interface MessageResult {
    /** Unique message identifier (on success) */
    message_id?: string;
    
    /** Updated registration token (if canonical_ids > 0) */
    registration_id?: string;
    
    /** Error code (on failure) */
    error?: string;
}

Error Handling

// Common error codes in MessageResult.error:
// 'NotRegistered' - Token is no longer valid
// 'InvalidRegistration' - Token format is invalid  
// 'MismatchSenderId' - Token doesn't match sender ID
// 'MessageTooBig' - Message payload exceeds size limit
// 'QuotaExceeded' - Sending quota exceeded
// 'Unavailable' - FCM service temporarily unavailable
// 'InternalServerError' - FCM internal error

// HTTP status codes passed to callback as error:
// 400 - Bad request (authentication, malformed request)
// 401 - Unauthorized (invalid API key)
// 5xx - Server errors (retry automatically handled)

Response Processing Example:

sender.send(message, { registrationTokens: tokens }, function(err, response) {
    if (err) {
        if (err === 401) {
            console.error('Authentication failed - check API key');
        } else if (err >= 500) {
            console.error('FCM server error:', err);
        } else {
            console.error('Send error:', err);
        }
        return;
    }

    console.log(`Sent to ${response.success} devices successfully`);
    console.log(`Failed to send to ${response.failure} devices`);
    console.log(`${response.canonical_ids} tokens need updating`);

    // Process individual results
    response.results.forEach((result, index) => {
        const token = tokens[index];
        
        if (result.message_id) {
            console.log(`Success for token ${token}: ${result.message_id}`);
            
            // Handle token updates
            if (result.registration_id) {
                console.log(`Update token ${token} to ${result.registration_id}`);
                // Update token in your database
            }
        } else if (result.error) {
            console.log(`Error for token ${token}: ${result.error}`);
            
            // Handle specific errors
            if (result.error === 'NotRegistered') {
                console.log(`Remove invalid token: ${token}`);
                // Remove token from your database
            }
        }
    });
});

Advanced Features

Proxy Configuration

const sender = new gcm.Sender('YOUR_API_KEY', {
    proxy: 'http://proxy.company.com:8080',
    timeout: 30000
});

Custom Headers

const sender = new gcm.Sender('YOUR_API_KEY', {
    headers: {
        'X-Custom-Header': 'custom-value'
    }
});

Debug Logging

Enable debug logging using the DEBUG environment variable:

DEBUG=node-gcm node your-app.js

Important Notes

  • API Key: Requires FCM server API key (Legacy API) - obtain from Firebase Console
  • Batch Limits: Maximum 1000 registration tokens per request
  • Rate Limits: Respect FCM rate limits to avoid quota exceeded errors
  • Token Management: Monitor response results to update/remove invalid tokens
  • Retry Logic: Failed requests are automatically retried with exponential backoff
  • Error Codes: 4xx errors are not retried (permanent failures), 5xx errors are retried
  • Response Order: Results array order matches recipient array order for token correlation

docs

constants.md

index.md

message.md

sender.md

tile.json