| Subcribe via RSS

Building Server Push Notifications with Appcelerator Titanium Cloud

May 5th, 2012 Posted in Apple, apps, Titanium

Appcelerator has blessed us developers with cloud services since release of Titanium 2. Even free registered users get 1 million server push messages a month free. Server push notification means that you can send users push notifications even when the app is not running on the device.
Cloud also gives lots of nice stuff for developers which eases the pain and the need of a custom back-end for your mobile app.

Although Appcelerator allows server push, many developers find it difficult to set it up. One of them being myself a couple of days ago, therefore I thought I’d give back to the community and wrote a little tutorial showing hot to make Server Push Notifications work for your app. I will concentrate mostly on certificate management, which is the most painful part of setting up Push Notifications on Apple devices.

 

1. Start a new Titanium project in Titanium studio. For this example we’ll call it PushTest and give an app ID com.teemusk.pushtest

Project setup in Titanium Studio

Project Setup. Make sure Cloud-enable this application is checked. Alternatively you can enable Cloud services on tiapp.xml editor.

Add a simple code to your app.js to open a window and run your app on simulator once so it’ll get registered and enabled on Titanium. The code for app.js looks like this right now:

var win = Titanium.UI.createWindow({
title:'TestPush iOS App',
backgroundColor:'#fff'
});
win.open();

1.3. Run your app on simulator once to see if it is ok. There should be nothing on the screen. Just white background.

2. Set up the cloud services and Certificates

2.1. Go to https://my.appcelerator.com/apps and find PushTest app from the list (you must be logged in to see that).
Your newly created app on Appcelerator

As you can see you have Cloud services already enabled for this app. That’s great.
2.2. Click Manage and check the settings for this app
2.3. Click Settings on top tabs. As you can see Apple iOS push certificates is empty. You will have to obtain a certificate from Apple iOS Provisioning Portal (you have to be an Apple developer to do this).
2.4. go to iOS Provisioning Portal through developer.apple.com and to Provisioning portal after logging in on Member area.
2.5. Create new App ID by choosing App IDs from left and then clicking ‘New App’ on top right corner.
2.6. Add PushTest as an app name and com.<yourdomain>.pushtest as an app id. Then click Done.
2.7. Now as you can see from the list your app is not quite set up for push notifications. You will have to configure it.
Push notifications not configured on Provisioning Portal

2.8. click Configure next to your app and Enable Apple Push Notifications on the following screen.

2.9. Next part is a bit tricky as you’ll have to work through some different things to do this, but basically you will have to get a certificate for your app to get Push Notifications working. Click Configure button next to ‘Development Push SSL Certificate’. The page that opens up is self explanatory. But in case you don’t want to read all this stuff then shortly it’ll go as follows:
2.10. Open up Keychain Access software on your mac. Choose ‘Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority…’ from top menu.
Obtain a Certificate

This will open up a dialog where just click ‘Save to Disk’ and ‘OK’ and then save the incoming certificate to your Desktop. Click ‘Save’ and ‘Done’.
2.11. You have a certificate on your desktop. It’s filename is ‘CertificateSigningRequest.certSigningRequest’.
2.12 Go back to Provisioning Portal and upload this file back to Apple. click ‘continue’, ‘choose file’, choose the certificate you just saved on desktop and click ‘Generate’. This will take a couple of seconds, but after it’s done click next and download the certification with your name called ‘aps_development.cer’.

2.13. Double click on the downloaded .cer file and it’ll be added to Keychain Access.
2.14. Select the certificate in Keychain Access with the name com.<yourdomain>.pushtest and right click (or command click) on it to open popup menu. Choose Export “Apple Development iOS Push Services” from this menu and save this file with extension .p12 on your disk. You will be asked for a password. Remember what you put in there. This is the final certificate you will have to upload to Appcelerator my apps.

2.15. Now, go back to Appcelerator my app settings for PushTest app and browse and upload the newly created .p12 certificate. Also add the password you chose in 1.16. in the box next to it.

Great, you’re done with the painful part of the tutorial. Now it’s good old titanium scripting again.

3. Code the app
I consider this tutorial not to be a scripting tutorial. Therefore I will just paste my app.js code below. I tried to comment my code so you can see what each function does. This code works on your phone. To run it on your phone you will have get a provisioning profile from Apple Provisioning Portal. I also uploaded an app.js for you to download and investigate.
The results of this code will add 4 buttons on the stage. When running the app on your phone the first time start pressing the buttons from top and after each tap wait for success alert dialog. Once you reached the end you’re all set.
var Cloud = require('ti.cloud');var trace = Ti.API.info;
var user_device_token = Ti.App.Properties.getString("device_token",null)var win = Titanium.UI.createWindow({
title:'TestPush iOS App',
backgroundColor:'#fff'
});
win.open();function init(){
buildUI();
}
setTimeout(init,500);function buildUI(){
var register_local_push = Ti.UI.createButton({
width:200,
height:30,
top:30,
title:"REGISTER LOCAL PUSH"
});
win.add(register_local_push);
register_local_push.addEventListener('click',getDeviceToken);var register_user_btn = Ti.UI.createButton({
width:200,
height:30,
top:70,
title:"REGISTER USER"
});
win.add(register_user_btn);
register_user_btn.addEventListener('click',registerUser);var login_btn = Ti.UI.createButton({
width:200,
height:30,
top:110,
title:"LOGIN"
});
win.add(login_btn);
login_btn.addEventListener('click',login);var register_server_push_btn = Ti.UI.createButton({
width:200,
height:30,
top:150,
title:"REGISTER SERVER PUSH"
});
win.add(register_server_push_btn);
register_server_push_btn.addEventListener('click',subscribeToServerPush);
}//REGISTER USER ON CLOUD
function registerUser(){
trace("REGISTER");
Cloud.Users.create({
username: "new_username",
password: "new_password",
password_confirmation: "new_password",
first_name: "Firstname",
last_name: "Lastname"
}, function (e) {
if (e.success) {
alert("USER CREATED SUCCESSFULLY.");
// user created successfully
} else {
// oops, something went wrong
alert("USER not created. something went wrong "+e);
}
});
}//LOGIN TO CLOUD AS A USER THAT WE CREATED BEFORE
function login(){
Cloud.Users.login({
login: 'new_username',
password: 'new_password'
}, function (e) {
if (e.success) {
var user = e.users[0];
alert('Success:\\n' +
'id: ' + user.id + '\\n' +
'first name: ' + user.first_name + '\\n' +
'last name: ' + user.last_name);
} else {
alert('Error:\\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
}//REGISTER LOCAL PUSH NOTIFICATION HERE
function getDeviceToken(){
trace("REGISTERING LOCAL PUSH");
Titanium.Network.registerForPushNotifications({
types: [
Titanium.Network.NOTIFICATION_TYPE_BADGE,
Titanium.Network.NOTIFICATION_TYPE_ALERT,
Titanium.Network.NOTIFICATION_TYPE_SOUND
],
success:function(e)
{
user_device_token = e.deviceToken;
Ti.App.Properties.setString("device_token",user_device_token);
alert("Device token received "+user_device_token);
},
error:function(e)
{
alert("Error during registration: "+e.error);
},
callback:function(e)
{
// called when a push notification is received.
alert("Received a push notification\n\nPayload:\n\n"+JSON.stringify(e.data));
}});

}
//REGISTER SERVER PUSH
function subscribeToServerPush(){
Cloud.PushNotifications.subscribe({
channel: 'friend_request',
type:'ios',
device_token: user_device_token
}, function (e) {
if (e.success) {
alert('Success'+((e.error && e.message) || JSON.stringify(e)));
} else {
alert('Error:\\n' + ((e.error && e.message) || JSON.stringify(e)));
}
});
}

 The code above is also uploaded as a file. You can download it here

4. Send your first Server Push notification
After running the app.js code on your iPhone start to tap the buttons from top to bottom. After each tap wait for the alert message with success message.
The app looks like this:

When you’re done with this sequence you’ll ready to send your first push.
Go to Appcelerator my apps section. Choose ‘notifications’ from the tab on top and check that you have a device registered with server push. My window looks like this:

Close the app on your phone (close it totally from bottom). Fill in the fields and push send notification. Now wait a bit to receive the push on your phone.

 

That’s it. I hope you get it working and find that it’s actually quite simple once you get it to work the first time. Also I hope this tutorial saves your time a bit.

Thanks for reading.

Tanel Teemusk
teemusk.com 

 

 

 

EDIT:

An extra checklist for debugging.
1. You cannot use wildcard development certificate for trying this. be sure to use com.yourdomain.yourapp or similar and not com.yourdomain.* or anything that involves asterisk. Otherwise push won’t work. (Thanks to TaMaX for pointing this out)
2. After your app goes live to AppStore be sure to upload another p12 certificate to Appcelerator using iOS Production Push certificate from Keychain Assistant. Development Push certificate won’t work after going live. (Thanks for DevMan for pointing this out)

54 Responses to “Building Server Push Notifications with Appcelerator Titanium Cloud”

  1. prabu Says:

    Hi,

    Thanks for sharing. I have tried to implement the cloud push notification in iOS. I have did everything as per the above documentation. No error occur while registration.

    In cloud console I can see “1 iOS client clients subscribed to push notifications”. Everything seems fine but I cant able to receive the push notification.

    How long will take to receive push notification after the registration?


  2. kinwai Says:

    Very good cloud usage and push notification article.
    Study a lot. Many thanks to you.


  3. Tanel Teemusk Says:

    Prabu: Notification should be received instantly. It takes about 1 second to get a push from server on my case with the code I shared.
    If you get no error and you see 1 iOS client subscribed then you should be all set. Maybe restarting your phone helps here?
    You should also see if your phone is set up correctly to receive push by going Settings>Notifications on your phone and see if your app is on the list there (In Notification Center).

    kinwal: Thanks ;)


  4. prabu Says:

    Hi,

    I can able to seen my application setup under Settings>Notifications in my phone and every thing seems fine. But still I didn’t get push notification.

    Also I have closed my app.


  5. Tanel Teemusk Says:

    prabu: This is really strange. I recommend you try with another password and username and register your user once again. Maybe something is wrong from cloud-side.


  6. prabu Says:

    I think I have done certification section correctly, that why in cloud console it appears like “1 iOS client clients subscribed to push notifications”.

    Am I correct? Also I am using correct password and username because I got correct callback response. How could I solve this issue?


  7. Tanel Teemusk Says:

    Really difficult. I can’t really say what could be wrong. Have you asked from Appcelerator community?


  8. prabu Says:

    I have asked but no response


  9. Tanel Teemusk Says:

    Well, in this case I’m thinking you might want to start all over from start. Make new app with new id, all the certificates etc. At least that’s something I would do. I’ve managed to get all my apps working with server push using this recipe.


  10. Colin Says:

    Hi,

    Thanks for the wonderful guide! I am wondering whether the device can register the user automatically when the app starts?

    Currently a button needs to be pressed. How can i get passed this?

    thanks
    colin


  11. Tanel Teemusk Says:

    @Colin Sure it can. I just built the buttons so I can control when something happens. It will also work if you don’t use buttons to trigger the registration code but run it when the app starts.


  12. jayesh Says:

    This Certificated is not yet valid

    i got this error while insert certificate in keychain Access


  13. Tanel Teemusk Says:

    This probably means that some of your certificates were expired. Renew and try again.


  14. jayesh Says:

    Project Works in Simulator

    but With provisional Profile not Works on Device.


  15. Tanel Teemusk Says:

    What happens on device? Does not start at all? You should definetly get the latest provisioning profile. Also it might be the case that you used Production push sertificate and development provisioning certificate, then it won’t work either. It’s a matter of testing it out with certificates. I know it’s a pain and takes time, but once you get a hang of it, it’ll be much easier in the future.

    Have fun!


  16. jayesh Says:

    On device Application Hangs With

    Programme receive SIGBAT signals.

    My provisional profiles i can attatch it wit h iphone and also i can upload p12 in titanium Setting for ACS.


  17. DevMan Says:

    Hi
    First, thank you for your good tutorial. That’s help me.

    This works in development : Everything works fine, I received my notification.

    But in production, I didn’t received any notification.

    To be more simple, I create only one user for all my iOS clients but no notification was received !

    Do you know where the problem can be and how to solve it ?

    Thanks


  18. Tanel Teemusk Says:

    DevMan,

    Shortly, you are probably trying to do push with Development certificate. You have to use Production Certificate after your app goes live.

    In the Provisioning portal at Apple you can export two types of certificates: Development push certificate and Production push certificate. When your app goes live then Development certificate will no longer work. Then you should do the Certification (p12) magic again on your Production certificate and upload it to Appcelerator to make it work.

    Let me know if this helps.

    Tanel


  19. DevMan Says:

    I think I used the Production Certificate (I remember that there was 2 types (Dev and Prod)).

    But I will check again. May be I need to re export my Production certificate after my app goes live.

    I will test tonight and will let you know :-)

    Thanks


  20. Thomas Says:

    Hi,
    First, thak you for your tuto :)
    i have question, where u get the module ti.cloudpush ? i checked on appcelerator marketplace but i didn’t find it :(
    Have you link pls ?
    thx you


  21. Tanel Teemusk Says:

    DevMan. Try to re export and let me know. My own app is not submitted yet so I don’t have a hands-on experience on how it’ll work after going live.

    Thomas. You get the Cloudpush module with Titanium Mobile SDK 2+ version. It’s already included when you update the sdk in Titanium Studio. Let me know if it helps.

    Tanel


  22. DevMan Says:

    HI TANEL

    Thanks for the tip
    … It works now


  23. TaMaX Says:

    Fantastic article!

    You shuld also remember ,that you cannot use wildcard provisioning profile for testing.

    I figured it out after 30 minutes of “wtf?!” ;)


  24. Tanel Teemusk Says:

    Thanks TaMaX for pointing this out. I added an additional checklist to end of this post which includes your comment about the wildcar thing.


  25. Jonathan Robort Says:

    Cloud also gives lots of nice stuff with well modification for developers which eases the pain and the need of a custom back-end for your mobile app.Thanks for well information.


  26. Cricket La Chica (@cricketlachica) Says:

    Hey man, thank you so much for this! I don’t have any questions or anything, I just wanted to say thank you for this tutorial. Much appreciated! High five!

    For the others, I had the issue of not being able to receive the push notification right away – but restarting my phone fixed the issue. I sent another push notification after restarting and the previous one that I sent came along with it (as if something was blocking it before and it was just pushed by the newer push notification).


  27. Tanel Teemusk Says:

    Thanks @Cricket La Chica
    Yeah I had such a pain making it work the first time and thought I’m not the only one. That’s why I thought tutorial would be nice;)

    Glad you got it working (Y)


  28. Kolin Says:

    hi Tanel,

    Thank you for the most helpful tutorial. My push notification is successful for an arbitrary user. However, I am a little confused here. When I want to distribute my app on the app store, can i continue to use the arbitrary user? If not, how can i register the users individually?


  29. Tanel Teemusk Says:

    Kolin, each phone has it’s own device token. so you will have to register users with their device tokens and then use the tokens to send device to individual users.


  30. Kolin Says:

    Hi Tanel,

    Thank you for the clarification. Really appreciates it.

    I would be grateful if you could advise me how do i display the pushed message only.

    alert(“Received a push notification\n\nPayload:\n\n”+JSON.stringify(e.data))

    without the strings of “aps”, “….”.

    i tried e.data, e.message

    but i still couldn’t display it like “Received a push notifications “This is the Message”.


  31. Dharmik Says:

    @all : I have the same problem that face @Prabu . i create new app and certificate again but unfortunatly that same problem occur again. i show the device but notification is not send on phon successfully. thanx. :(


  32. Mose Joseph Says:

    I have created App ID, Enabled APNS and Created Provision File also, but when click Register Local Push, it throw the following error

    “Error Domain=NSCocoaErrorDomain Code=3000 UserInfo=0x113e80 “no valid ‘aps-environment’ entitlement string found for application”

    I have followed the above given steps , but no luck.

    Pl. help.


  33. Angela Says:

    I’ve got the same error of @Mose when I click the “Register Local Push” button.
    Could someone pls help me?

    Thank you so much!


  34. Alfredo Says:

    Works perfect! Thanks for your complete information. Do you Know how to implement on Android?


  35. Tanel Teemusk Says:

    Alfredo, I’m glad it worked for you. Unfortunately I have no idea how to make this work on android. If you find a good tutorial about android push notification setup on appcelerator titanium, let me know as well. Could use this functionality for some of my apps.
    Cheers.


  36. Chris DCosta Says:

    @Mose Joseph and @Angela, I had the same problem but managed to get it working.

    The problem is that your iOS device provisioning profile was created before you enabled push notifications on the app. Recreate the Provisioning Profile on your Apple Dev account. Download and install the provisioning cert [it will show up as a new certificate] under Xcode. Now in Appcelerator, under EDIT->RUN CONFIGURATIONS you need set the new provisioning profile to your app under the ‘Titanium Application iOS installer – YourAppName’ option.

    It should build and work perfectly now!

    =====
    @Tanel Teemusk thank you so much for this AWESOME post! had me up and running within an hour!


  37. Tanel Teemusk Says:

    No probs @Chris. I had a really hard time getting my push working. Could not find much information so I decided this post might help out people like me.
    Also thanks for troubleshooting some comments. I sometimes cannot tell what could be the problem.
    But anyway, yes. Chris DCosta is right and this should be emphasized. If something does not work, be sure you have all the latest certificates from Apple before you export your p12 file.


  38. Paul Says:

    Hi Tanel

    I’ve created over 20 apps using Titanium, but I’m looking for help with in-app purchases. Do you have any video tutorials that you can recommend?

    Thanks for your help
    Paul
    Founder
    appFanz.com


  39. Tanel Teemusk Says:

    Paul,

    Unfortunately I don’t have any tutorials on iap. I have managed to make them work quite well myself though with Storekit module. What problems do you have? When I get time I can do a tutorial on that.


  40. Felipe Says:

    Tanel,

    I had follow all the steps and it looks fine on the simulator, but when I try to run the app on my iPhone i get the error:
    [ERROR] Script Error = Couldn’t find module: ti.cloud.
    Am working with Titanium 2.1.0

    Please help!


  41. Tanel Teemusk Says:

    Felipe,

    That means your iCloud module did not install on device. I suggest you delete the app from your device and then clean your project (delete iphone directory from yourapp/build/) and recompile to device. This should do the trick.

    also make sure your tiapp.xml includes the iCloud module.


  42. Edouard Says:

    Hi,
    In your code, a missing coma may cause a failure when building.
    It is right after : var user_device_token = Ti.App.Properties.getString(“device_token”,null)
    Hope this helpt


  43. Sin Dedos Says:

    Everything works great except when I click the fourth button where the application calls the function subscribeToServerPush, I receive an error message that says Push Notification Certificate Not Configured. So close!

    What could be the issue?


  44. Vy Phan Says:

    Awesome!!! Thanks for great post.

    I am still confused about how it works, With Titanium cloud, we don’t need to setup server to send Push notifications?

    I also don’t see how to send Push notifications by programing (In your guide, the example was sent from notifications in Appcelerator site).

    VyPhan


  45. Tanel Teemusk Says:

    Vy Phan,
    Titanium cloud already is a server. So no we don’t need any extra servers.
    This is Server Push notification tutorial. It means that we can send messages to users from the web.
    There is actually a thing calles Local notifications. This is done without a server.
    check: http://bencoding.com/2012/06/10/using-local-notifications-in-titanium/ for more info.


  46. Vy Phan Says:

    Tanel, thanks for your rapid reply.

    Can you see my sceranio:
    I have a website (ASP.NET) to manage my customers where i can create/udpate/delete ones.
    I also have an Ipad app to see able my customer information (list / detail).

    Now, i want to have notifications to all Ipad devices (even their application is closed) anywhen my customers changes by website.

    All of features is done. Now i want to apply push notificatios. Could you please give your suggestion.

    VyPhan


  47. Thiago Says:

    My push notifications not working. I need to change something in the code?
    I tap the buttons from top to bottom, the button register local push its work, but the rest of the buttons doesnt work. Do I need configure something in code?

    Sorry for my bad english.


  48. Tanel Teemusk Says:

    @Thiago

    Extremely hard to tell. This code worked for me when I wrote the tutorial.

    The most common things that go wrong are things related to the certificate. Also note that acs (the cloud) gives your app a unique id etc.

    I suggest you try to recreate the tutorial one by one. I know people get this to work like this.


  49. Tanel Teemusk Says:

    @VyPhan
    For each device you will get a device token. This will be unique. You can then send out push notification for each registered device.
    I’m not sure if it is possible to register several devices to one user in acs, but you can do this yourself via .net technologies.
    The thing is that if you do your own backend, then you don’t have to use appcelerator cloud at all. You can actually handle device/user management and sending push notifications straight via apple using server-side technologies yourself.
    I’m not a backend guy myself, but I’ve worked with backend guys who managed to get it working in a half a day with ease. So I’m guessing it should be rather simple thing to do if you’re good with server-side technologies and json api’s.


  50. Peter Says:

    Thanks for this tutorial! It was a huge help. Having to create the user and login in every time just to use push notifications seemed like a huge hassle though when not using all the other features of ACS. I finally realized you could skip the user process by using subscribeToken instead of just subscribe.

    http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.Cloud.PushNotifications-method-subscribeToken


  51. Rajanish Says:

    This is an excellent example for push. Thanks a ton!


  52. Simbu Says:

    Hi Tanel Teemusk,

    Thanks for this post.Really its helpful to me.
    And i could see the 3 subscribed devices like below.

    You currently have 3 iOS clients, 0 Android clients subscribed to push notifications.

    Also i got the below push log for first time.
    Push Notification Logs for 533931fe15d8270b631bb9cb
    iOS count Android count Sending Status Sent At
    1 0 Over Due 2014-03-31T09:14:42.085Z

    But i am not getting this on my iPhone..and under settings/notification i can see my app.

    Then every time i try to send push notification got the below message :

    422 Unprocessable Entity – The app is not setup for push notification

    Can you please explain what went wrong..?


  53. Arley Andrada Maria Says:

    I just released a Push Notification module for Android and iOS, with direct connection to APN (Apple) and GCM (Google), without to require ACS, UrbanAirship or any push broker contract or fee; Receive unlimited free push notifications in your apps.

    [buy PushClient at Appcelerator Marketplace](https://marketplace.appcelerator.com/apps/10615)


  54. Krish Says:

    Hi,
    Thank you for the wonderful tutorial.

    Just a query. Lets say im planning to just retrieve the device token using ACS and then using a 3rd party system to ‘push’ the notifications. Would i have to purchase a subscription with Appcelerator or can i simply make use of the registerForPushNotication Method and go ahead with using the


Leave a Reply

  • Ads