Skip to content
This repository has been archived by the owner on Sep 4, 2020. It is now read-only.

Commit

Permalink
Add features: push.subscribe, push.unsubscribe (issue #1040) (#1227)
Browse files Browse the repository at this point in the history
  • Loading branch information
hung-doan authored and macdonst committed Oct 13, 2016
1 parent cf7ce8e commit bb0d3ed
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 21 deletions.
47 changes: 47 additions & 0 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
- [push.on('error')](#pushonerror-callback)
- [push.off()](#pushoffevent-callback)
- [push.unregister()](#pushunregistersuccesshandler-errorhandler-topics)
- [push.subscribe()](#pushsubscribetopic-successhandler-errorhandler)
- [push.unsubscribe()](#pushunsubscribetopic-successhandler-errorhandler)
- [push.setApplicationIconBadgeNumber() - iOS & Android only](#pushsetapplicationiconbadgenumbersuccesshandler-errorhandler-count---ios--android-only)
- [push.getApplicationIconBadgeNumber() - iOS only](#pushgetapplicationiconbadgenumbersuccesshandler-errorhandler---ios-only)
- [push.finish() - iOS only](#pushfinishsuccesshandler-errorhandler-id---ios-only)
Expand Down Expand Up @@ -281,6 +283,51 @@ push.unregister(function() {
});
```

## push.subscribe(topic, successHandler, errorHandler)

The subscribe method is used when the application wants to subscribe a new topic to receive push notifications.

### Parameters

Parameter | Type | Default | Description
--------- | ---- | ------- | -----------
`topic` | `String` | | Topic to subscribe to.
`successHandler` | `Function` | | Is called when the api successfully subscribes.
`errorHandler` | `Function` | | Is called when the api encounters an error while subscribing.

### Example

```javascript
push.subscribe('my-topic', function() {
console.log('success');
}, function(e) {
console.log('error:');
console.log(e);
});
```
## push.unsubscribe(topic, successHandler, errorHandler)

The unsubscribe method is used when the application no longer wants to receive push notifications from a specific topic but continue to receive other push messages.

### Parameters

Parameter | Type | Default | Description
--------- | ---- | ------- | -----------
`topic` | `String` | | Topic to unsubscribe from.
`successHandler` | `Function` | | Is called when the api successfully unsubscribe.
`errorHandler` | `Function` | | Is called when the api encounters an error while unsubscribing.

### Example

```javascript
push.unsubscribe('my-topic', function() {
console.log('success');
}, function(e) {
console.log('error:');
console.log(e);
});
```

## push.setApplicationIconBadgeNumber(successHandler, errorHandler, count) - iOS & Android only

Set the badge count visible when the app is not running
Expand Down
2 changes: 2 additions & 0 deletions src/android/com/adobe/phonegap/push/PushConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public interface PushConstants {
public static final String STYLE_TEXT = "text";
public static final String BADGE = "badge";
public static final String INITIALIZE = "init";
public static final String SUBSCRIBE = "subscribe";
public static final String UNSUBSCRIBE = "unsubscribe";
public static final String UNREGISTER = "unregister";
public static final String EXIT = "exit";
public static final String FINISH = "finish";
Expand Down
91 changes: 80 additions & 11 deletions src/android/com/adobe/phonegap/push/PushPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,40 @@ public void run() {
callbackContext.success();
}
});
} else if (SUBSCRIBE.equals(action)){
// Subscribing for a topic
cordova.getThreadPool().execute(new Runnable() {
public void run() {
try {
SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE);
String token = sharedPref.getString(REGISTRATION_ID, "");
String topic = data.getString(0);
subscribeToTopic(topic, token);
callbackContext.success();
} catch (JSONException e) {
callbackContext.error(e.getMessage());
} catch (IOException e) {
callbackContext.error(e.getMessage());
}
}
});
} else if (UNSUBSCRIBE.equals(action)){
// un-subscribing for a topic
cordova.getThreadPool().execute(new Runnable(){
public void run() {
try {
SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE);
String token = sharedPref.getString(REGISTRATION_ID, "");
String topic = data.getString(0);
unsubscribeFromTopic(topic, token);
callbackContext.success();
} catch (JSONException e) {
callbackContext.error(e.getMessage());
} catch (IOException e) {
callbackContext.error(e.getMessage());
}
}
});
} else {
Log.e(LOG_TAG, "Invalid action : " + action);
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.INVALID_ACTION));
Expand Down Expand Up @@ -293,23 +327,45 @@ private void clearAllNotifications() {
notificationManager.cancelAll();
}

private void subscribeToTopics(JSONArray topics, String registrationToken) {
/**
* Transform `topic name` to `topic path`
* Normally, the `topic` inputed from end-user is `topic name` only.
* We should convert them to GCM `topic path`
* Example:
* when topic name = 'my-topic'
* then topic path = '/topics/my-topic'
*
* @param String topic The topic name
* @return The topic path
*/
private String getTopicPath(String topic)
{
return "/topics/" + topic;
}

private void subscribeToTopics(JSONArray topics, String registrationToken) throws IOException {
if (topics != null) {
String topic = null;
for (int i=0; i<topics.length(); i++) {
try {
topic = topics.optString(i, null);
if (topic != null) {
Log.d(LOG_TAG, "Subscribing to topic: " + topic);
GcmPubSub.getInstance(getApplicationContext()).subscribe(registrationToken, "/topics/" + topic, null);
}
} catch (IOException e) {
Log.e(LOG_TAG, "Failed to subscribe to topic: " + topic, e);
}
topic = topics.optString(i, null);
subscribeToTopic(topic, registrationToken);
}
}
}

private void subscribeToTopic(String topic, String registrationToken) throws IOException
{
try {
if (topic != null) {
Log.d(LOG_TAG, "Subscribing to topic: " + topic);
GcmPubSub.getInstance(getApplicationContext()).subscribe(registrationToken, getTopicPath(topic), null);
}
} catch (IOException e) {
Log.e(LOG_TAG, "Failed to subscribe to topic: " + topic, e);
throw e;
}
}

private void unsubscribeFromTopics(JSONArray topics, String registrationToken) {
if (topics != null) {
String topic = null;
Expand All @@ -318,7 +374,7 @@ private void unsubscribeFromTopics(JSONArray topics, String registrationToken) {
topic = topics.optString(i, null);
if (topic != null) {
Log.d(LOG_TAG, "Unsubscribing to topic: " + topic);
GcmPubSub.getInstance(getApplicationContext()).unsubscribe(registrationToken, "/topics/" + topic);
GcmPubSub.getInstance(getApplicationContext()).unsubscribe(registrationToken, getTopicPath(topic));
}
} catch (IOException e) {
Log.e(LOG_TAG, "Failed to unsubscribe to topic: " + topic, e);
Expand All @@ -327,6 +383,19 @@ private void unsubscribeFromTopics(JSONArray topics, String registrationToken) {
}
}

private void unsubscribeFromTopic(String topic, String registrationToken) throws IOException
{
try {
if (topic != null) {
Log.d(LOG_TAG, "Unsubscribing to topic: " + topic);
GcmPubSub.getInstance(getApplicationContext()).unsubscribe(registrationToken, getTopicPath(topic));
}
} catch (IOException e) {
Log.e(LOG_TAG, "Failed to unsubscribe to topic: " + topic, e);
throw e;
}
}

/*
* serializes a bundle to JSON.
*/
Expand Down
2 changes: 2 additions & 0 deletions src/ios/PushPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@

- (void)init:(CDVInvokedUrlCommand*)command;
- (void)unregister:(CDVInvokedUrlCommand*)command;
- (void)subscribe:(CDVInvokedUrlCommand*)command;
- (void)unsubscribe:(CDVInvokedUrlCommand*)command;

- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
Expand Down
74 changes: 64 additions & 10 deletions src/ios/PushPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ -(void)initGCMRegistrationHandler;
[weakSelf registerWithToken:registrationToken];
} else {
NSLog(@"Registration to GCM failed with error: %@", error.localizedDescription);
[weakSelf failWithMessage:@"" withError:error];
[weakSelf failWithMessage:self.callbackId withMsg:@"" withError:error];
}
};
}
Expand Down Expand Up @@ -124,8 +124,6 @@ - (void)didDeleteMessagesOnServer {

- (void)unregister:(CDVInvokedUrlCommand*)command;
{
self.callbackId = command.callbackId;

NSArray* topics = [command argumentAtIndex:0];

if (topics != nil) {
Expand All @@ -146,7 +144,63 @@ - (void)unregister:(CDVInvokedUrlCommand*)command;
}
} else {
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
[self successWithMessage:@"unregistered"];
[self successWithMessage:command.callbackId withMsg:@"unregistered"];
}
}

- (void)subscribe:(CDVInvokedUrlCommand*)command;
{
NSString* topic = [command argumentAtIndex:0];

if (topic != nil) {
NSLog(@"subscribe from topic: %@", topic);
id pubSub = [GCMPubSub sharedInstance];
[pubSub subscribeWithToken: [self gcmRegistrationToken]
topic:[NSString stringWithFormat:@"/topics/%@", topic]
options:nil
handler:^void(NSError *error) {
if (error) {
if (error.code == 3001) {
NSLog(@"Already subscribed to %@", topic);
[self successWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Already subscribed to %@", topic]];
} else {
NSLog(@"Failed to subscribe to topic %@: %@", topic, error);
[self failWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Failed to subscribe to topic %@", topic] withError:error];
}
}
else {
NSLog(@"Successfully subscribe to topic %@", topic);
[self successWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Successfully subscribe to topic %@", topic]];
}
}];
} else {
NSLog(@"There is no topic to subscribe");
[self successWithMessage:command.callbackId withMsg:@"There is no topic to subscribe"];
}
}

- (void)unsubscribe:(CDVInvokedUrlCommand*)command;
{
NSString* topic = [command argumentAtIndex:0];

if (topic != nil) {
NSLog(@"unsubscribe from topic: %@", topic);
id pubSub = [GCMPubSub sharedInstance];
[pubSub unsubscribeWithToken: [self gcmRegistrationToken]
topic:[NSString stringWithFormat:@"/topics/%@", topic]
options:nil
handler:^void(NSError *error) {
if (error) {
NSLog(@"Failed to unsubscribe to topic %@: %@", topic, error);
[self failWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Failed to unsubscribe to topic %@", topic] withError:error];
} else {
NSLog(@"Successfully unsubscribe to topic %@", topic);
[self successWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Successfully unsubscribe to topic %@", topic]];
}
}];
} else {
NSLog(@"There is no topic to unsubscribe");
[self successWithMessage:command.callbackId withMsg:@"There is no topic to unsubscribe"];
}
}

Expand Down Expand Up @@ -435,7 +489,7 @@ - (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
return;
}
NSLog(@"Push Plugin register failed");
[self failWithMessage:@"" withError:error];
[self failWithMessage:self.callbackId withMsg:@"" withError:error];
}

- (void)notificationReceived {
Expand Down Expand Up @@ -555,12 +609,12 @@ - (void)hasPermission:(CDVInvokedUrlCommand *)command
[self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId];
}

-(void)successWithMessage:(NSString *)message
-(void)successWithMessage:(NSString *)callbackId withMsg:(NSString *)message
{
if (self.callbackId != nil)
if (callbackId != nil)
{
CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message];
[self.commandDelegate sendPluginResult:commandResult callbackId:self.callbackId];
[self.commandDelegate sendPluginResult:commandResult callbackId:callbackId];
}
}

Expand All @@ -574,12 +628,12 @@ -(void)registerWithToken:(NSString*)token; {
}


-(void)failWithMessage:(NSString *)message withError:(NSError *)error
-(void)failWithMessage:(NSString *)callbackId withMsg:(NSString *)message withError:(NSError *)error
{
NSString *errorMessage = (error) ? [NSString stringWithFormat:@"%@ - %@", message, [error localizedDescription]] : message;
CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorMessage];

[self.commandDelegate sendPluginResult:commandResult callbackId:self.callbackId];
[self.commandDelegate sendPluginResult:commandResult callbackId:callbackId];
}

-(void) finish:(CDVInvokedUrlCommand*)command
Expand Down
46 changes: 46 additions & 0 deletions www/push.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,52 @@ PushNotification.prototype.unregister = function(successCallback, errorCallback,
exec(cleanHandlersAndPassThrough, errorCallback, 'PushNotification', 'unregister', [options]);
};

/**
* subscribe to a topic
* @param {String} topic topic to subscribe
* @param {Function} successCallback success callback
* @param {Function} errorCallback error callback
* @return {void}
*/
PushNotification.prototype.subscribe = function(topic, successCallback, errorCallback) {
if (!errorCallback) { errorCallback = function() {}; }

if (typeof errorCallback !== 'function') {
console.log('PushNotification.subscribe failure: failure parameter not a function');
return;
}

if (typeof successCallback !== 'function') {
console.log('PushNotification.subscribe failure: success callback parameter must be a function');
return;
}

exec(successCallback, errorCallback, 'PushNotification', 'subscribe', [topic]);
};

/**
* unsubscribe to a topic
* @param {String} topic topic to unsubscribe
* @param {Function} successCallback success callback
* @param {Function} errorCallback error callback
* @return {void}
*/
PushNotification.prototype.unsubscribe = function(topic, successCallback, errorCallback) {
if (!errorCallback) { errorCallback = function() {}; }

if (typeof errorCallback !== 'function') {
console.log('PushNotification.unsubscribe failure: failure parameter not a function');
return;
}

if (typeof successCallback !== 'function') {
console.log('PushNotification.unsubscribe failure: success callback parameter must be a function');
return;
}

exec(successCallback, errorCallback, 'PushNotification', 'unsubscribe', [topic]);
};

/**
* Call this to set the application icon badge
*/
Expand Down

0 comments on commit bb0d3ed

Please sign in to comment.