Easy interface for Google's Cloud Messaging service (now Firebase Cloud Messaging)
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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.
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
});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');
});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);
}
});Different ways to specify message recipients.
// Send to a single device
const recipient = 'eHcE7r_bNzE:APA91bF...'; // Registration token string
sender.send(message, recipient, callback);// 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);// Send to a topic
const recipient = { topic: 'news' };
sender.send(message, recipient, callback);
// Alternative format
const recipient = '/topics/news';
sender.send(message, recipient, callback);// Send based on topic conditions
const recipient = {
condition: "'sports' in topics && 'news' in topics"
};
sender.send(message, recipient, callback);// Send to device group (notification key)
const recipient = {
notificationKey: 'APA91bH...' // Device group key
};
sender.send(message, recipient, callback);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 retriesUnderstanding FCM response structure for processing results.
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;
}// 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
}
}
});
});const sender = new gcm.Sender('YOUR_API_KEY', {
proxy: 'http://proxy.company.com:8080',
timeout: 30000
});const sender = new gcm.Sender('YOUR_API_KEY', {
headers: {
'X-Custom-Header': 'custom-value'
}
});Enable debug logging using the DEBUG environment variable:
DEBUG=node-gcm node your-app.js