Appcelerator/ Titanium: Cannot send push notification to Android

487 Views Asked by At

I want to be able to send push notifications using Titanium and Arrow Push on Android.

I have followed the instructions here:

Configuring Push Services

Subscribing to push notifications

Modules.CloudPush

My simple code looks as follows:

var CloudPush = require('ti.cloudpush');
var deviceToken = null;
    
// Works fine
CloudPush.retrieveDeviceToken({
    success: function () {
        deviceToken = e.deviceToken;
        alert('deviceToken: ' + deviceToken);
        subscribeToChannel();
    },
    error: function () {
        alert('Failed to register for push notifications! ' + e.error);
    }
});
    
// Never runs!!!
CloudPush.addEventListener('callback', function (evt) {
    Ti.API.info('New notification!');
    alert("Notification received: " + evt.payload);
});

// Works fine
function subscribeToChannel () {
    Cloud.PushNotifications.subscribeToken({
        device_token: deviceToken,
        channel: 'general',
        type: Ti.Platform.name
    }, function (e) {
        if (e.success) {
            alert('Subscribed');
        } else {
            alert('Error:\n' + ((e.error && e.message) || JSON.stringify(e)));
        }
    });
}

Most of the above code is similar to the docs. The subscription aspect of the code seems to works perfectly fine, as the user's device also appears in the devices section of the Appcelerator Dashboard.

However when it comes to sending a notification, from the Appcelerator Dashboard, the word "Failure" appears next to my Android device.

Error on push notifications

The full error message when highlighting the "?" icon is as follows:

Exception Type: GCM; Error Code: 3103; Error Message: RegistrationId(s) is null or empty; Catched Exception: argument cannot be null

I looked this error up on http://docs.appcelerator.com/arrowdb/latest/#!/guide/troubleshooting and all it says is:

The GCM client provided a null or empty registration ID. This error is uncommon if you are using the Modules.CloudPush module.

Which isn't helpful.

What am I doing wrong? Is this a bug on Accelerator side.

3

There are 3 best solutions below

0
Yahya Uddin On BEST ANSWER

Turns out my code was fine. The credentials I was using however was incorrect. Please see my other related question here:

Appcelerator/ Titanium: Getting Android credentials to push notifications

The docs are in need of updating.

6
Jonathan Wheat On

I'm hardly an expert with push, but I compared what you have to what I have in one of my apps.

Pretty sure you need to send the deviceToken into the subscribeToChannel function.

Try changing this -

function subscribeToChannel () {

to this -

function subscribeToChannel (deviceToken) {

then add the token to the call here -

subscribeToChannel (deviceToken);

Let me know if that works for you.

-Jon

5
AstrovicApps On

On subscribeToChannel() function, you should use type : 'gcm' instead of type: Ti.Platform.name

This is a commonJS module that I created for my Android push:

function ACSPush(_callback) {

    var debug_mode = true;
    var Cloud = require('ti.cloud');        
    var CloudPush = require('ti.cloudpush');
    CloudPush.enabled = true; 
    var deviceToken;

    CloudPush.retrieveDeviceToken({
        success : function deviceTokenSuccess(e) {
            if(debug_mode)
                Ti.API.info('Device Token: ' + e.deviceToken);
            deviceToken = e.deviceToken;
            if(Ti.App.Properties.getString("deviceToken") != deviceToken.toString()){
                defaultSubscribe();
            };
        },
        error : function deviceTokenError(e) {
            if(debug_mode)
                Ti.API.info('deviceTokenError.. :( ' + e.error);
        }
    });

    function defaultSubscribe() {
        Cloud.PushNotifications.subscribeToken({
            channel : 'MyChannel',
            device_token : deviceToken,
            type : 'gcm'
        }, function(e) {
            if(e.success) {
                if(debug_mode)
                    Ti.API.info("Success registerForPushNotifications");
                Ti.App.Properties.setString("deviceToken", deviceToken.toString());
            } else {
                if(debug_mode)
                    Ti.API.info('Error:\n' + ((e.error && e.message) || JSON.stringify(e)));
            };
        });
    };

    CloudPush.addEventListener('callback', function(evt) {
        var payload = JSON.parse(evt.payload);
        if(debug_mode){
            Ti.API.info("Received a push notification\nPayload:\n" + JSON.stringify(evt.payload));
            Ti.API.info("payload: " + payload);
        };
        _callback(payload);
    });
    CloudPush.addEventListener('trayClickLaunchedApp', function(evt) {
        if(debug_mode)
            Ti.API.info('Tray Click Launched App (app was not running)');
    });
    CloudPush.addEventListener('trayClickFocusedApp', function(evt) {
        if(debug_mode)
            Ti.API.info('Tray Click Focused App (app was already running)');
    });

};

module.exports = ACSPush;

Obviously, you must first configure Android Push Service http://docs.appcelerator.com/platform/latest/#!/guide/Configuring_push_services-section-src-37551713_Configuringpushservices-ConfiguringpushservicesforAndroiddevices