npm package: @parse/node-gcm
Description: Easy interface for Google's Cloud Messaging service (now Firebase Cloud Messaging)
Author: Marcus Farkas
Latest version: 1.0.2

# node-gcm

[![Join the chat at https://gitter.im/ToothlessGear/node-gcm](https://badges.gitter.im/ToothlessGear/node-gcm.svg)](https://gitter.im/ToothlessGear/node-gcm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![npm](https://badge.fury.io/js/node-gcm.svg)](https://www.npmjs.com/package/node-gcm)

The goal of this project is providing the best and most easily used interface for Firebase Cloud Messaging. (The name `gcm` comes from the older name for the service, Google Cloud Messaging.)

**By April 11, 2019 users must have [migrated from GCM to FCM](https://developers.google.com/cloud-messaging/android/android-migrate-fcm).**
If you are using this library, we've already got you covered on the server side (since version 0.14.1) --- just update to the most recent version and you are good.

We appreciate all the help we can get!
If you want to help out, check out the [Guidelines for Contributing](CONTRIBUTING.md) section.

If you are developing an open-source project with a broader scope (like a full Firebase suite), we would love for you to use node-gcm internally.

See the [official FCM documentation](https://firebase.google.com/docs/cloud-messaging/) for more information.

We are currently working on version 2.0.0 of the project, and it is available in an early alpha version.
Follow [PR #238](https://github.com/ToothlessGear/node-gcm/pull/238) to see current status.

## Installation

```bash
$ npm install node-gcm --save
```

**Note:** This package requires Node v4.0 and newer.

## Requirements

This library provides the server-side implementation of GCM.
You need to generate an [API Key](https://developers.google.com/cloud-messaging/gcm#apikey).

GCM notifications can be sent to both [Android](https://developers.google.com/cloud-messaging/android/start) and [iOS](https://developers.google.com/cloud-messaging/ios/start).
If you are new to GCM you should probably look into the [documentation](https://developers.google.com/cloud-messaging/gcm).

## Example application

According to below **Usage** reference, we could create such application:

```js
var gcm = require('node-gcm');

// Set up the sender with your GCM/FCM API key (declare this once for multiple messages)
var sender = new gcm.Sender('YOUR_API_KEY_HERE');

// Prepare a message to be sent
var message = new gcm.Message({
    data: { key1: 'msg1' }
});

// Specify which registration IDs to deliver the message to
var regTokens = ['YOUR_REG_TOKEN_HERE'];

// Actually send the message
sender.send(message, { registrationTokens: regTokens }, function (err, response) {
	if (err) console.error(err);
	else console.log(response);
});
```

## Usage

```js
var gcm = require('node-gcm');

// Create a message
// ... with default values
var message = new gcm.Message();

// ... or some given values
var message = new gcm.Message({
	collapseKey: 'demo',
	priority: 'high',
	contentAvailable: true,
	delayWhileIdle: true,
	timeToLive: 3,
	restrictedPackageName: "somePackageName",
	dryRun: true,
	data: {
		key1: 'message1',
		key2: 'message2'
	},
	notification: {
		title: "Hello, World",
		icon: "ic_launcher",
		body: "This is a notification that will be displayed if your app is in the background."
	}
});

// Change the message data
// ... as key-value
message.addData('key1','message1');
message.addData('key2','message2');

// ... or as a data object (overwrites previous data object)
message.addData({
	key1: 'message1',
	key2: 'message2'
});

// Set up the sender with you API key
var sender = new gcm.Sender('insert Google Server API Key here');

// Add the registration tokens of the devices you want to send to
var registrationTokens = [];
registrationTokens.push('regToken1');
registrationTokens.push('regToken2');

// Send the message
// ... trying only once
sender.sendNoRetry(message, { registrationTokens: registrationTokens }, function(err, response) {
  if(err) console.error(err);
  else    console.log(response);
});

// ... or retrying
sender.send(message, { registrationTokens: registrationTokens }, function (err, response) {
  if(err) console.error(err);
  else    console.log(response);
});

// ... or retrying a specific number of times (10)
sender.send(message, { registrationTokens: registrationTokens }, 10, function (err, response) {
  if(err) console.error(err);
  else    console.log(response);
});

// Q: I need to remove all "bad" token from my database, how do I do that? 
//    The results-array does not contain any tokens!
// A: The array of tokens used for sending will match the array of results, so you can cross-check them.
sender.send(message, { registrationTokens: registrationTokens }, function (err, response) {  
  var failed_tokens = response.results                           // Array with result for each token we messaged
    .map((res, i) => res.error ? registrationTokens[i] : null)   // If there's any kind of error, 
                                                                 // pick _the token_ from the _other_ array
    .filter(token => token);                                     // Remove all the null values
  console.log('These tokens are no longer ok:', failed_tokens);
});
```
## Recipients

You can send push notifications to various recipient types by providing one of the following recipient keys:


|Key|Type|Description|
|---|---|---|
|to|String|A single [registration token](https://developers.google.com/cloud-messaging/android/client#sample-register), [notification key](https://developers.google.com/cloud-messaging/notifications), or [topic](https://developers.google.com/cloud-messaging/topic-messaging).
|topic|String|A single publish/subscribe topic.
|condition|String|Multiple topics using the [condition](https://firebase.google.com/docs/cloud-messaging/topic-messaging) parameter.
|notificationKey|String|Deprecated. A key that groups multiple registration tokens linked to the same user.
|registrationIds|String[]|Deprecated. Use registrationTokens instead.|
|registrationTokens|String[]|A list of registration tokens. Must contain at least 1 and at most 1000 registration tokens.|

If you provide an incorrect recipient key or object type, an `Error` object will be returned to your callback.

Notice that [you can *at most* send notifications to 1000 registration tokens at a time](https://github.com/ToothlessGear/node-gcm/issues/42).
This is due to [a restriction](http://developer.android.com/training/cloudsync/gcm.html) on the side of the GCM API.


### Additional message options

|Parameter|Usage|Description|
|---|---|---|
|collapseKey|Optional, string|This parameter identifies a group of messages that can be collapsed, so that only the last message gets sent when delivery can be resumed.|
|priority|Optional, string|Sets the priority of the message. Valid values are "normal" and "high."|
|contentAvailable|Optional, JSON boolean|On iOS, when a notification or message is sent and this is set to true, an inactive client app is awoken.|
|timeToLive|Optional, JSON number|This parameter specifies how long (in seconds) the message should be kept in GCM storage if the device is offline. The maximum time to live supported is 4 weeks, and the default value is 4 weeks.|
|restrictedPackageName|Optional, string|This parameter specifies the package name of the application where the registration tokens must match in order to receive the message.|
|dryRun|Optional, JSON boolean|This parameter, when set to true, allows developers to test a request without actually sending a message.|
|data|Optional, JSON object|This parameter specifies the custom key-value pairs of the message's payload.|
|notification|Optional, JSON object|This parameter specifies the predefined, user-visible key-value pairs of the notification payload. See "Notification payload option table" below for more details.|

## Notification usage

```js

var message = new gcm.Message();

// Add notification payload as key value
message.addNotification('title', 'Alert!!!');
message.addNotification('body', 'Abnormal data access');
message.addNotification('icon', 'ic_launcher');

// as object
message.addNotification({
  title: 'Alert!!!',
  body: 'Abnormal data access',
  icon: 'ic_launcher'
});

```

**Note:** Notifications sent using `message.addNotification` are only displayed when your app is in the background. Consider sending the notification parameters using `message.addData` and manually building and displaying a notification in your push receiver logic.

### Notification payload option table

|Parameter|Platform|Usage|Description|
|---|---|---|---|
|title|Android, iOS (Watch)|Required (Android), Optional (iOS), string|Indicates notification title. This field is not visible on iOS phones and tablets.|
|body|Android, iOS|Optional, string|Indicates notification body text.|
|icon|Android|Required, string|Indicates notification icon. On Android: sets value to myicon for drawable resource myicon.png.|
|sound|Android, iOS|Optional, string|Indicates sound to be played. Supports only default currently.|
|badge|iOS|Optional, string|Indicates the badge on client app home icon.|
|tag|Android|Optional, string|Indicates whether each notification message results in a new entry on the notification center on Android. If not set, each request creates a new notification. If set, and a notification with the same tag is already being shown, the new notification replaces the existing one in notification center.|
|color|Android|Optional, string|Indicates color of the icon, expressed in #rrggbb format|
|click_action|Android, iOS|Optional, string|The action associated with a user click on the notification. On Android, if this is set, an activity with a matching intent filter is launched when user clicks the notification. For example, if one of your Activities includes the intent filter: (Appendix:1)Set click_action to OPEN_ACTIVITY_1 to open it. If set, corresponds to category in APNS payload.|
|body_loc_key|iOS|Optional, string|Indicates the key to the body string for localization. On iOS, this corresponds to "loc-key" in APNS payload.|
|body_loc_args|iOS|Optional, JSON array as string|Indicates the string value to replace format specifiers in body string for localization. On iOS, this corresponds to "loc-args" in APNS payload.|
|title_loc_args|iOS|Optional, JSON array as string|Indicates the string value to replace format specifiers in title string for localization. On iOS, this corresponds to "title-loc-args" in APNS payload.|
|title_loc_key|iOS|Optional, string|Indicates the key to the title string for localization. On iOS, this corresponds to "title-loc-key" in APNS payload.|

Notice notification payload defined in [GCM Connection Server Reference](https://developers.google.com/cloud-messaging/server-ref#table1)

## Custom HTTP request options

You can provide custom `request` options such as `proxy` and `timeout` for the HTTP request to the GCM API. For more information, refer to [the complete list of request options](https://github.com/request/request#requestoptions-callback). Note that the following options cannot be overriden: `method`, `uri`, `body`, as well as the following headers: `Authorization`, `Content-Type`, and `Content-Length`.

```js
// Set custom request options
var requestOptions = {
	proxy: 'http://127.0.0.1:8888',
	timeout: 5000
};

// Set up the sender with your API key and request options
var sender = new gcm.Sender('YOUR_API_KEY_HERE', requestOptions);

// Prepare a GCM message...

// Send it to GCM endpoint with modified request options
sender.send(message, { registrationTokens: regTokens }, function (err, response) {
    if(err) console.error(err);
    else     console.log(response);
});
```

## GCM client compatibility

As of January 9th, 2016, there are a few known compatibility issues with 3rd-party GCM client libraries:

### phonegap-plugin-push

* [No support for subscribing to PubSub topics](https://github.com/phonegap/phonegap-plugin-push/issues/79)
* [Requirement for `data` payload object when sending a `notification` object](https://github.com/phonegap/phonegap-plugin-push/issues/387)
* [Requirement for all 3 `notification` fields when sending a `notification` object (title, icon, message)](https://github.com/ToothlessGear/node-gcm/issues/180)

These issues are out of this project's context and can only be fixed by the respective 3rd-party project maintainers.

## Debug

To enable debug mode (print requests and responses to and from GCM),
set the `DEBUG` environment flag when running your app (assuming you use `node app.js` to run your app):

```bash
DEBUG=node-gcm node app.js
```

## Donate

 Bitcoin: [13iTQf7tDhrKgibw2Y3U5SyPJa7R8sQmHQ](https://blockchain.info/address/13iTQf7tDhrKgibw2Y3U5SyPJa7R8sQmHQ)