{ "id": "162031", "key": "MOD-2276", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10034", "key": "MOD", "name": "Appcelerator Modules", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": null, "resolutiondate": null, "created": "2016-07-24T16:30:58.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [], "versions": [], "issuelinks": [], "assignee": { "name": "gmathews", "key": "gmathews", "displayName": "Gary Mathews", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2018-11-14T17:17:59.000+0000", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "components": [ { "id": "12140", "name": "CloudPush" } ], "description": "h6.Reproduce Step\r\n1. Run the following code in app.js\r\n{code}\r\nvar win = Ti.UI.createWindow({});\r\n\r\nvar CloudPush = require('ti.cloudpush'); \r\nvar Cloud = require('ti.cloud');\r\n\r\nvar deviceToken = null;\r\n\r\nCloudPush.singleCallback = true;\r\n\r\nCloudPush.retrieveDeviceToken({\t\r\n\tsuccess: function deviceTokenSuccess(e) {\r\n\t\tdeviceToken = e.deviceToken;\r\n\t\tTi.API.info('Device Token: ' + e.deviceToken);\r\n \t\t\r\n \tloginUser();\r\n },\r\n error: function deviceTokenError(e) {\r\n alert('Failed to register for push! ' + e.error);\r\n }\r\n});\r\n\r\nCloudPush.addEventListener('callback', function (evt) {\r\n alert(evt.payload);\r\n Ti.API.info(\"CallBack fired: \\n\" + evt.payload);\r\n});\r\nCloudPush.addEventListener('trayClickLaunchedApp', function (evt) {\r\n\talert('Tray Click Launched App (app was not running)');\r\n Ti.API.info('Tray Click Launched App (app was not running)');\r\n});\r\nCloudPush.addEventListener('trayClickFocusedApp', function (evt) {\r\n\talert('Tray Click Focused App (app was already running)');\r\n Ti.API.info('Tray Click Focused App (app was already running)');\r\n});\r\n\r\nfunction loginUser(){\r\n Cloud.Users.login({\r\n login: 'sliang@appcelerator.com',\r\n password: '1234'\r\n }, function (e) {\r\n if (e.success) {\r\n Ti.API.info('Login successful');\r\n subscribeToChannel();\r\n } else {\r\n alert('Error:\\n' +\r\n ((e.error && e.message) || JSON.stringify(e)));\r\n }\r\n });\r\n}\r\n\r\nfunction subscribeToChannel(){\r\n Cloud.PushNotifications.subscribe({\r\n channel: 'alert',\r\n device_token: deviceToken,\r\n type: Ti.Platform.name == 'android' ? 'android' : 'ios'\r\n }, function (e) {\r\n if (e.success) {\r\n Ti.API.info('Subscribed');\r\n } else {\r\n alert('Error:\\n' +\r\n ((e.error && e.message) || JSON.stringify(e)));\r\n }\r\n });\r\n}\r\n\r\nwin.open();\r\n{code}\r\n2. Send push notification from dashboard, make sure the push working well.\r\n3. Close the app and remove it from recent.\r\n4. Send push notification again.\r\n5. Click the tray notification to open the app.\r\n\r\nh6.Expect Result\r\ncallback and trayClickLaunchedApp event should be triggered both.\r\n\r\nh6.Actual Result\r\nonly trayClickLaunchedApp event triggered, callback event did not get called.\r\n\r\nh6.Note\r\nIf you only put the app in background, then it works well as expected.\r\n", "attachment": [], "flagged": false, "summary": "Android CloudPush: Callback event did not fire if close app and remove from recent", "creator": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "subtasks": [], "reporter": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "environment": "TISDK 5.3.1 and 5.2.2\r\nCloudPush Module 3.4.1", "closedSprints": [ { "id": 1058, "state": "closed", "name": "2018 Sprint 16 SDK", "startDate": "2018-07-29T22:26:06.486Z", "endDate": "2018-08-12T22:26:00.000Z", "completeDate": "2018-08-13T17:38:16.757Z", "originBoardId": 114 }, { "id": 1065, "state": "closed", "name": "2016 Sprint 17 SDK", "startDate": "2018-08-13T17:39:36.846Z", "endDate": "2018-08-27T17:39:00.000Z", "completeDate": "2018-08-29T16:10:57.013Z", "originBoardId": 114 }, { "id": 1034, "state": "closed", "name": "2018 Sprint 10 SDK", "startDate": "2018-05-07T00:03:21.636Z", "endDate": "2018-05-21T00:03:00.000Z", "completeDate": "2018-05-20T20:54:58.928Z", "originBoardId": 114 }, { "id": 1035, "state": "closed", "name": "2018 Sprint 11 SDK", "startDate": "2018-05-20T20:57:43.542Z", "endDate": "2018-06-03T20:57:00.000Z", "completeDate": "2018-06-04T15:13:14.425Z", "originBoardId": 114 }, { "id": 1070, "state": "closed", "name": "2018 Sprint 18 SDK", "startDate": "2018-08-26T16:14:35.297Z", "endDate": "2018-09-09T16:14:00.000Z", "completeDate": "2018-09-11T20:59:21.495Z", "originBoardId": 114 }, { "id": 1039, "state": "closed", "name": "2018 Sprint 12 SDK", "startDate": "2018-06-03T15:22:23.401Z", "endDate": "2018-06-17T15:22:00.000Z", "completeDate": "2018-06-18T20:45:36.363Z", "originBoardId": 114 }, { "id": 1073, "state": "closed", "name": "2018 Sprint 19 SDK", "startDate": "2018-09-09T21:02:56.422Z", "endDate": "2018-09-23T21:02:00.000Z", "completeDate": "2018-09-23T22:28:10.932Z", "originBoardId": 114 }, { "id": 1045, "state": "closed", "name": "2018 Sprint 13 SDK", "startDate": "2018-06-17T20:47:13.621Z", "endDate": "2018-07-01T20:47:00.000Z", "completeDate": "2018-07-02T18:40:05.029Z", "originBoardId": 114 }, { "id": 1078, "state": "closed", "name": "2018 Sprint 20 SDK", "startDate": "2018-09-23T16:57:58.349Z", "endDate": "2018-10-07T16:57:00.000Z", "completeDate": "2018-10-07T23:31:40.476Z", "originBoardId": 114 }, { "id": 1050, "state": "closed", "name": "2018 Sprint 14 SDK", "startDate": "2018-07-01T18:40:57.193Z", "endDate": "2018-07-15T18:40:00.000Z", "completeDate": "2018-07-16T03:27:08.720Z", "originBoardId": 114 }, { "id": 1084, "state": "closed", "name": "2018 Sprint 21", "startDate": "2018-10-07T23:32:40.560Z", "endDate": "2018-10-21T23:32:00.000Z", "completeDate": "2018-10-21T23:19:05.460Z", "originBoardId": 114 }, { "id": 1053, "state": "closed", "name": "2018 Sprint 15 SDK", "startDate": "2018-07-15T21:52:05.453Z", "endDate": "2018-07-29T21:52:00.000Z", "completeDate": "2018-07-29T22:25:11.723Z", "originBoardId": 114 }, { "id": 126, "state": "closed", "name": "2018 Sprint 05 SDK", "startDate": "2018-02-25T19:38:08.926Z", "endDate": "2018-03-11T18:38:00.000Z", "completeDate": "2018-03-11T22:06:01.520Z", "originBoardId": 100 }, { "id": 1088, "state": "closed", "name": "2018 Sprint 22", "startDate": "2018-10-21T23:20:52.653Z", "endDate": "2018-11-04T23:20:00.000Z", "completeDate": "2018-11-04T23:29:59.423Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "391778", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "Sample code for classic app:\r\n{code}\r\nvar win = Ti.UI.createWindow({});\r\n \r\nvar CloudPush = require('ti.cloudpush'); \r\nvar Cloud = require('ti.cloud');\r\n\r\nvar env = Ti.App.deployType.toLowerCase() === 'production' ? 'production' : 'development',\r\n username = Ti.App.Properties.getString('acs-username-'+env),\r\n password = Ti.App.Properties.getString('acs-password-'+env);\r\n\r\n\r\nvar deviceToken = null;\r\n \r\nCloudPush.singleCallback = true;\r\n \r\nCloudPush.retrieveDeviceToken({ \r\n success: function deviceTokenSuccess(e) {\r\n deviceToken = e.deviceToken;\r\n Ti.API.info('Device Token: ' + e.deviceToken);\r\n \r\n loginUser();\r\n },\r\n error: function deviceTokenError(e) {\r\n alert('Failed to register for push! ' + e.error);\r\n }\r\n});\r\n \r\nCloudPush.addEventListener('callback', function (evt) {\r\n alert(evt.payload);\r\n Ti.API.info(\"CallBack fired: \\n\" + evt.payload);\r\n});\r\nCloudPush.addEventListener('trayClickLaunchedApp', function (evt) {\r\n alert('Tray Click Launched App (app was not running)');\r\n Ti.API.info('Tray Click Launched App (app was not running)\\n' + evt.payload);\r\n});\r\nCloudPush.addEventListener('trayClickFocusedApp', function (evt) {\r\n alert('Tray Click Focused App (app was already running)');\r\n Ti.API.info('Tray Click Focused App (app was already running)\\n' + evt.payload);\r\n});\r\n \r\nfunction loginUser(){\r\n \r\n Cloud.Users.login({\r\n login:username,\r\n password:password,\r\n }, function (e) {\r\n if (e.success) {\r\n Ti.API.info('Login successful');\r\n subscribeToChannel();\r\n } else {\r\n alert('Error:\\n' +\r\n ((e.error && e.message) || JSON.stringify(e)));\r\n }\r\n });\r\n}\r\n \r\nfunction subscribeToChannel(){\r\n Cloud.PushNotifications.subscribe({\r\n channel: 'alert',\r\n device_token: deviceToken,\r\n type: Ti.Platform.name == 'android' ? 'android' : 'ios'\r\n }, function (e) {\r\n if (e.success) {\r\n Ti.API.info('Subscribed');\r\n } else {\r\n alert('Error:\\n' +\r\n ((e.error && e.message) || JSON.stringify(e)));\r\n }\r\n });\r\n}\r\n \r\nwin.open();\r\n{code}", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-07-28T05:13:20.000+0000", "updated": "2016-07-28T05:19:21.000+0000" }, { "id": "391779", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "Tested with code above using 5.3.1.GA with latest ti.cloud 3.2.11 and ti.cloudpush 3.4.1. Not able to reproduce issue.\r\nTested with Android 6.0 Nexus 6.\r\n\r\nLogs show it works:\r\n{code}\r\n7-28 01:17:41.197 9527 9540 I ALERT : (KrollRuntimeThread) [242,264] {\"android\":{\"sound\":\"none\",\"alert\":\"Push With App not in Background\",\"vibrate\":false}}\r\n07-28 01:17:41.197 9527 9540 I TiAPI : CallBack fired: \r\n07-28 01:17:41.197 9527 9540 I TiAPI : {\"android\":{\"sound\":\"none\",\"alert\":\"Push With App not in Background\",\"vibrate\":false}}\r\n07-28 01:17:41.198 9527 9540 I ALERT : (KrollRuntimeThread) [1,265] Tray Click Launched App (app was not running)\r\n07-28 01:17:41.198 9527 9540 I TiAPI : Tray Click Launched App (app was not running)\r\n07-28 01:17:41.198 9527 9540 I TiAPI : {\"android\":{\"sound\":\"none\",\"alert\":\"Push With App not in Background\",\"vibrate\":false}}\r\n{code}", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-07-28T05:20:42.000+0000", "updated": "2016-07-28T05:24:15.000+0000" }, { "id": "391780", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "[~sliang] Not able to reproduce. It's working correctly for me.", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-07-28T05:21:48.000+0000", "updated": "2016-07-28T05:21:48.000+0000" }, { "id": "391785", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "Here's a workaround for it to work:\r\n{code}\r\n\r\n/*\r\n// this sets the background color of the master UIView (when there are no windows/tab groups on it)\r\nTitanium.UI.setBackgroundColor('#000');\r\n\r\n// create tab group\r\nvar tabGroup = Titanium.UI.createTabGroup();\r\n\r\n\r\n//\r\n// create base UI tab and root window\r\n//\r\nvar win1 = Titanium.UI.createWindow({ \r\n title:'Tab 1',\r\n backgroundColor:'#fff'\r\n});\r\nvar tab1 = Titanium.UI.createTab({ \r\n icon:'KS_nav_views.png',\r\n title:'Tab 1',\r\n window:win1\r\n});\r\n\r\nvar label1 = Titanium.UI.createLabel({\r\n\tcolor:'#999',\r\n\ttext:'I am Window 1',\r\n\tfont:{fontSize:20,fontFamily:'Helvetica Neue'},\r\n\ttextAlign:'center',\r\n\twidth:'auto'\r\n});\r\n\r\nwin1.add(label1);\r\n\r\n//\r\n// create controls tab and root window\r\n//\r\nvar win2 = Titanium.UI.createWindow({ \r\n title:'Tab 2',\r\n backgroundColor:'#fff'\r\n});\r\nvar tab2 = Titanium.UI.createTab({ \r\n icon:'KS_nav_ui.png',\r\n title:'Tab 2',\r\n window:win2\r\n});\r\n\r\nvar label2 = Titanium.UI.createLabel({\r\n\tcolor:'#999',\r\n\ttext:'I am Window 2',\r\n\tfont:{fontSize:20,fontFamily:'Helvetica Neue'},\r\n\ttextAlign:'center',\r\n\twidth:'auto'\r\n});\r\n\r\nwin2.add(label2);\r\n\r\n\r\n\r\n//\r\n// add tabs\r\n//\r\ntabGroup.addTab(tab1); \r\ntabGroup.addTab(tab2); \r\n\r\n\r\n// open tab group\r\ntabGroup.open();\r\n*/\r\n\r\n// added during app creation. this will automatically login to\r\n// ACS for your application and then fire an event (see below)\r\n// when connected or errored. if you do not use ACS in your\r\n// application as a client, you should remove this block\r\n(function(){\r\nvar ACS = require('ti.cloud'),\r\n env = Ti.App.deployType.toLowerCase() === 'production' ? 'production' : 'development',\r\n username = Ti.App.Properties.getString('acs-username-'+env),\r\n password = Ti.App.Properties.getString('acs-password-'+env);\r\n\r\n// if not configured, just return\r\nif (!env || !username || !password) { return; }\r\n\r\nACS.Users.login({\r\n\tlogin:username,\r\n\tpassword:password,\r\n}, function(result){\r\n\tif (env==='development') {\r\n\t\tTi.API.info('ACS Login Results for environment `'+env+'`:');\r\n\t\tTi.API.info(result);\r\n\t}\r\n\tif (result && result.success && result.users && result.users.length){\r\n\t\tTi.App.fireEvent('login.success',result.users[0],env);\r\n\t} else {\r\n\t\tTi.App.fireEvent('login.failed',result,env);\r\n\t}\r\n});\r\n\r\n})();\r\n\r\nvar win = Ti.UI.createWindow({});\r\n \r\nvar CloudPush = require('ti.cloudpush'); \r\nvar Cloud = require('ti.cloud');\r\n\r\nvar env = Ti.App.deployType.toLowerCase() === 'production' ? 'production' : 'development',\r\n username = Ti.App.Properties.getString('acs-username-'+env),\r\n password = Ti.App.Properties.getString('acs-password-'+env);\r\n\r\n\r\nvar deviceToken = null;\r\n \r\nCloudPush.singleCallback = true;\r\n \r\nCloudPush.retrieveDeviceToken({ \r\n success: function deviceTokenSuccess(e) {\r\n deviceToken = e.deviceToken;\r\n Ti.API.info('Device Token: ' + e.deviceToken);\r\n \r\n loginUser();\r\n },\r\n error: function deviceTokenError(e) {\r\n alert('Failed to register for push! ' + e.error);\r\n }\r\n});\r\n \r\nCloudPush.addEventListener('callback', function (evt) {\r\n setTimeout(function(){\r\n alert(\"CallBack fired: \\n\" + evt.payload);\r\n }, 1000);\r\n Ti.API.info(\"CallBack fired: \\n\" + evt.payload);\r\n});\r\nCloudPush.addEventListener('trayClickLaunchedApp', function (evt) {\r\n alert('Tray Click Launched App (app was not running)\\n'+ evt.payload);\r\n Ti.API.info('Tray Click Launched App (app was not running)\\n' + evt.payload);\r\n});\r\nCloudPush.addEventListener('trayClickFocusedApp', function (evt) {\r\n alert('Tray Click Focused App (app was already running)\\n'+ evt.payload);\r\n Ti.API.info('Tray Click Focused App (app was already running)\\n' + evt.payload);\r\n});\r\n \r\nfunction loginUser(){\r\n \r\n Cloud.Users.login({\r\n login:username,\r\n password:password,\r\n }, function (e) {\r\n if (e.success) {\r\n Ti.API.info('Login successful');\r\n subscribeToChannel();\r\n } else {\r\n alert('Error:\\n' +\r\n ((e.error && e.message) || JSON.stringify(e)));\r\n }\r\n });\r\n}\r\n \r\nfunction subscribeToChannel(){\r\n Cloud.PushNotifications.subscribe({\r\n channel: 'alert',\r\n device_token: deviceToken,\r\n type: Ti.Platform.name == 'android' ? 'android' : 'ios'\r\n }, function (e) {\r\n if (e.success) {\r\n Ti.API.info('Subscribed');\r\n } else {\r\n alert('Error:\\n' +\r\n ((e.error && e.message) || JSON.stringify(e)));\r\n }\r\n });\r\n}\r\n \r\nwin.open();\r\n{code}", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-07-28T06:23:55.000+0000", "updated": "2016-07-28T06:23:55.000+0000" }, { "id": "391786", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "I believe, what's happening is that the \"Callback\" event is being called before the App is properly set up.\r\nThus, the {{Ti.API.info}} comes out fine. But anything that has a UI element, eg {{alert()}} won't be called correctly as the App is not ready (timing of the thread).\r\n\r\nThe workaround around above uses a timeout function for 1 second before showing the alert.\r\n{code}\r\nsetTimeout(function(){\r\n alert(\"CallBack fired: \\n\" + evt.payload);\r\n }, 1000);\r\n{code}\r\n\r\n[~sliang] Is this workaround acceptable? If so, I'll resolve it.\r\n\r\nUpdate with more information: It has to do with the Activity being available and getting the context in order to do the alert.", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-07-28T06:26:58.000+0000", "updated": "2016-07-28T06:45:40.000+0000" }, { "id": "391798", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "Leaving this ticket open as we should take a look to make sure that this workaround is not needed in the future.", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-07-28T06:51:19.000+0000", "updated": "2016-07-28T06:54:05.000+0000" }, { "id": "437811", "author": { "name": "shumne", "key": "shumne", "displayName": "shumne", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Hey Guys,\r\n\r\nAny updates on this ticket?\r\nWe are still facing this issue on some Android devices specifically on Android 7!", "updateAuthor": { "name": "shumne", "key": "shumne", "displayName": "shumne", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-05-21T14:30:06.000+0000", "updated": "2018-05-21T14:30:06.000+0000" } ], "maxResults": 14, "total": 14, "startAt": 0 } } }