I have an app that uses Parse.com for push notifications. These are triggered with Cloud Code, but those notifications, while firing, are coming in silent, no sound, no vibration nothing. What is going wrong with it?
pushQuery.equalTo('channels', newUserId);
if (anonymous2 == "false") {
Parse.Push.send({
where: pushQuery, // Set our Installation query
data: {
alert: firstName2 + " " + lastName2 + " " + "just added a prayer request."
}
}, {
success: function() {
// Push was successful
},
error: function(error) {
throw "Got an error " + error.code + " : " + error.message;
}
});
}
Related
I am using cordova-plugin-advanced-http plugin for API calling and all JSON enabled API working fine but I have one XML embedded API which is working fine in Postman but while I call it from ionic its param not getting at the server end.
Below is my code for XML API:
Type 1:
let headers = {
"Content-type": 'text/xml; charset=utf-8',
"Authorization": token,
};
let xmlBody =
'<ServiceRequest>' +
'<CaseNumber>' + caseNumber +
'</CaseNumber>' +
'</ServiceRequest>'
this.httpPlugin.setDataSerializer('utf8');
this.httpPlugin.post('https://test.com/Service', xmlBody, headers).then((response) => {
console.log("XML Response : ", JSON.stringify(response.data));
xml2js.parseString(response.data, function (err, result) {
console.log("XML parser success:", result);
console.log("XML parser error:", err);
if (result) {
resolve(result);
} else {
reject(err);
}
});
}).catch(error => {
if (error.status == 403) {
console.log("Token expired : " + JSON.stringify(error));
} else {
console.log("Error : " + error.error);
console.log("Error " + JSON.stringify(error));
reject(error);
}
});
Type 2:
let xmlBody = '<ServiceRequest>' +
'<CaseNumber>' + caseNumber +
'</CaseNumber>' +
'</ServiceRequest>';
console.log("XML Body", xmlBody)
// this.httpPlugin.setRequestTimeout(60);
this.httpPlugin.setDataSerializer('utf8');
this.httpPlugin.setHeader('*', 'authorization', token);
this.httpPlugin.setHeader('*', 'Content-Type', "application/x-www-form-urlencoded");
this.httpPlugin.post('https://test.com/Service', xmlBody, {}).then((response) => {
console.log("XML Response : ", JSON.stringify(response.data));
xml2js.parseString(response.data, function (err, result) {
console.log("XML parser success:", result);
console.log("XML parser error:", err);
if (result) {
resolve(result);
} else {
reject(err);
}
});
}).catch(error => {
if (error.status == 403) {
console.log("Token expired : " + JSON.stringify(error));
} else {
console.log("Error : " + error.error);
console.log("Error " + JSON.stringify(error));
reject(error);
}
});
All the time it's throwing errors from the server and with the same request, I am able to get data in postman as well as Native iOS code.
I referred this issue on GitHub but still no success.
Something I am missing though it's not able to get data on the server.
Help me to solve this issue.
After struggling a lot on this issue I found a solution to clean my request cookies.
In the HTTP Advanced plugin, there is one method to clear my cookies.
clearCookies()
Clear all cookies.
Use this method before calling any API.
So what it will do clear all my cookies and my issue related to old cookies will be solved in this way.
constructor(
public storage: Storage,
public httpPlugin: HTTP,
private platform: Platform
) {
// enable SSL pinning
httpPlugin.setSSLCertMode("pinned");
//Clear old cookies
httpPlugin.clearCookies();
}
The above code solves my issue.
Thanks all for your quick guidance and suggestions.
comment on this if this is not the right way to clear my old request data.
I am developing iOS app with Phonegap.
I am implementing the process which incrementing badge number when app receives push notification usijng phonegap-plugin-push.
On the server side which sending push notification,
the badge number is not configured.
I want to implement the process when app receives push notification,
app counts the current badge number, increments it and set the badgenumber.
Using push.getApplicationIconBadgeNumber and push.setApplicationIconBadgeNumber,
below my code works well when app is Foreground,
But it doesn't work when app is Background, Suspended、Not running.
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
onDeviceReady: function() {
console.log('Received Device Ready Event');
console.log('calling setup push');
console.log('platform : '+device.platform);
if ((device.platform == 'iOS') || (device.platform == 'Android')) {
app.setupPush();
}
},
setupPush: function() {
console.log('calling push init');
var push = PushNotification.init({
"android": {
"senderID": "xxxxxxxxxx"
},
"browser": {},
"ios": {
"sound": true,
"vibration": true,
"badge": true
},
"windows": {}
});
push.on('registration', function(data) {
console.log('registration event: ' + data.registrationId);
var oldRegId = localStorage.getItem(key);
console.log('oldRegId : ' + oldRegId);
if (oldRegId !== data.registrationId) {
console.log('different ID');
localStorage.setItem(key, data.registrationId);
}
});
push.on('error', function(e) {
console.log("push error = " + e.message);
});
push.on('notification', function(data) {
console.log('notification event');
navigator.notification.alert(
data.message, // message
null, // callback
data.title, // title
'Ok' // buttonName
);
push.getApplicationIconBadgeNumber(function(count) {
console.log('get badge : ' + count);
count++;
push.setApplicationIconBadgeNumber(function() {
console.log('set badge : ' + count);
}, function() {
console.log('set badge error');
}, count);
}, function() {
console.log('get badge error');
});
});
}
};
On this site,
https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/API.md#pushfinishsuccesshandler-errorhandler-id---ios-only
push.setApplicationIconBadgeNumber is explained
"Set the badge count visible when the app is not running", and
push.getApplicationIconBadgeNumber is explained
"Get the current badge count visible when the app is not running".
But this my code, both 2 function works when app is Foreground,
and the badge number is not changed when app receives push notification on background state.
So, is the explanation written on that site wrong?
App works the same, nevertheless the push notification option "content-available" is configured 1 or not on the push notification sending server side.
So, please tell me what the code should I write.
-- Versions --
crodova version : 7.1.0
platform iOS : 4.5.4
phonegap-plugin-push : 1.10.6
I resolved it by myselr.
But, badge number is not updated when app states is "Not runnnig".
I supposes it is not possible to update badge number when app states is "Not runnnig".
So, it would be the specification of this app.
If you want to update badge number when app states is "Not running",
I think you can realize it with define badge number at the sending server side.
Below steps can resolve my problem.
*** 1 : Using cordova-plugin-background-fetch
Write below in config.xml.
<plugin name="cordova-plugin-background-fetch" source="npm" />
*** 2 : Enable "Background Refresh" of this app
For iPhone, you can enable it with
tapping "Settings -> General -> Background App Refresh".
*** 3 : Configure content-available=1 & id to sending data.
Below is the example of the sending data.
{ \"aps\": { \"alert\": \"Hello World\",\"content-available\": 1 }, \"id\" : 3 }
In this example, id is configured to 3.
This id is used at push.finish function (See next section).
*** 4 : Add push.finish function
Add this function into "push.on('notification', function(data){});".
The name of id of data.additionalData is corresponding to that of id of the sending data.
(Checking the specification of push.finish function at official site)
push.on('notification', function(data) {
console.log('notification event');
navigator.notification.alert(
data.message, // message
null, // callback
data.title, // title
'Ok' // buttonName
);
push.getApplicationIconBadgeNumber(function(count) {
//alert('get badge : ' + count);
console.log('get badge : ' + count);
count++;
push.setApplicationIconBadgeNumber(function() {
console.log('set badge : ' + count);
}, function() {
console.log('set badge error');
}, count);
}, function() {
console.log('get badge error: ' + count);
});
//alert('notId: ' + data.additionalData.notId);
console.log('notification id: ' + data.additionalData.id);
// do something with the push data
// then call finish to let the OS know we are done
push.finish(function() {
console.log("processing of push data is finished");
}, function() {
console.log("something went wrong with push.finish for ID =", data.additionalData.id)
}, data.additionalData.id);
});
I am using Appcelerator Studio.
I would like to get device token from iPhone. I am following the Appcelerator docs, however when the application installed it shows me the alert "do you want receive notification", and after the click on it nothing is printed in console.
Here is my code:
var self = Titanium.UI.createWindow({
backgroundColor : '#146FA6',
title : 'Menu',
});
var deviceToken = null;
// Check if the device is running iOS 8 or later
if (Ti.Platform.name == "iPhone OS" && parseInt(Ti.Platform.version.split(".")[0]) >= 8) {
// Wait for user settings to be registered before registering for push notifications
Ti.App.iOS.addEventListener('usernotificationsettings', function registerForPush() {
// Remove event listener once registered for push notifications
Ti.App.iOS.removeEventListener('usernotificationsettings', registerForPush);
Ti.Network.registerForPushNotifications({
success : function(e) {
var deviceToken = e.deviceToken;
alert(e.deviceToken);
Ti.API.info("Push notification device token is: " + deviceToken);
Ti.API.info("Push notification types: " + Titanium.Network.remoteNotificationTypes);
Ti.API.info("Push notification enabled: " + Titanium.Network.remoteNotificationsEnabled);
},
error : deviceTokenError,
callback : receivePush
});
});
// Register notification types to use
Ti.App.iOS.registerUserNotificationSettings({
types : [Ti.App.iOS.USER_NOTIFICATION_TYPE_ALERT, Ti.App.iOS.USER_NOTIFICATION_TYPE_SOUND, Ti.App.iOS.USER_NOTIFICATION_TYPE_BADGE]
});
}
// For iOS 7 and earlier
else {
Ti.Network.registerForPushNotifications({
// Specifies which notifications to receive
types : [Ti.Network.NOTIFICATION_TYPE_BADGE, Ti.Network.NOTIFICATION_TYPE_ALERT, Ti.Network.NOTIFICATION_TYPE_SOUND],
success : function(e) {
var deviceToken = e.deviceToken;
alert(deviceToken);
Ti.API.info("Push notification device token is: " + deviceToken);
Ti.API.info("Push notification types: " + Titanium.Network.remoteNotificationTypes);
Ti.API.info("Push notification enabled: " + Titanium.Network.remoteNotificationsEnabled);
},
error : deviceTokenError,
callback : receivePush
});
}
//deviceTokenSuccess();
// Process incoming push notifications
function receivePush(e) {
alert('Received push: ' + JSON.stringify(e));
}
function deviceTokenError(e) {
alert('Failed to register for push notifications! ' + e.error);
}
self.open();
If LiveView is enabled, disable it.
There are some known conflicts when using LiveView and push notification services
To disable LiveView function using the Titanium Studio, look at your Appcelerator Studio toolbar, like that
And deselect the first item.
The code should be like this
var self = Titanium.UI.createWindow({
backgroundColor : '#146FA6',
title : 'Menu',
});
var deviceToken = null;
// Check if the device is running iOS 8 or later
if (Ti.Platform.name == "iPhone OS" && parseInt(Ti.Platform.version.split(".")[0]) >= 8) {
// Wait for user settings to be registered before registering for push notifications
Ti.App.iOS.addEventListener('usernotificationsettings', function registerForPush() {
// Remove event listener once registered for push notifications
Ti.App.iOS.removeEventListener('usernotificationsettings', registerForPush);
Ti.Network.registerForPushNotifications({
success: deviceTokenSuccess,
error: deviceTokenError,
callback: receivePush
});
});
// Register notification types to use
Ti.App.iOS.registerUserNotificationSettings({
types: [
Ti.App.iOS.USER_NOTIFICATION_TYPE_ALERT,
Ti.App.iOS.USER_NOTIFICATION_TYPE_SOUND,
Ti.App.iOS.USER_NOTIFICATION_TYPE_BADGE
]
});
}
// For iOS 7 and earlier
else {
Ti.Network.registerForPushNotifications({
// Specifies which notifications to receive
types: [
Ti.Network.NOTIFICATION_TYPE_BADGE,
Ti.Network.NOTIFICATION_TYPE_ALERT,
Ti.Network.NOTIFICATION_TYPE_SOUND
],
success: deviceTokenSuccess,
error: deviceTokenError,
callback: receivePush
});
}
// Process incoming push notifications
function receivePush(e) {
alert('Received push: ' + JSON.stringify(e));
}
// Save the device token for subsequent API calls
function deviceTokenSuccess(e) {
deviceToken = e.deviceToken;
alert(deviceToken);
Ti.API.info("Push notification device token is: " + deviceToken);
Ti.API.info("Push notification types: " + Titanium.Network.remoteNotificationTypes);
Ti.API.info("Push notification enabled: " + Titanium.Network.remoteNotificationsEnabled);
}
function deviceTokenError(e) {
alert('Failed to register for push notifications! ' + e.error);
}
self.open();
I'm using Phonegap/cordova and writing a Android/iOS app which will download json data from my server and store locally on device for offline usage. On android, this works perfectly. I don't have an iOS device therefore relying on iOS simulator, and it throws me a "could not create target file" type error.
downloadFile:function(path,uri){
var fileTransfer = new FileTransfer();
fileTransfer.download(
encodeURI(path),
app.getStorageLocation()+"files/"+uri,
function(entry) {
console.log("download complete: " + entry.toURL());
app.progressMove();
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
},
false);
}
The getStorageLocation function is:
getStorageLocation:function(){
if(device.platform == 'Android'){
return cordova.file.externalApplicationStorageDirectory;
}
else if(device.platform == 'iOS'){
return cordova.file.documentsDirectory;
}else{
throw new Error('Unsupported platform: '+device.platform);
}
}
On iOS simulator, it does return the Documents directory, but the above fails to write to it. Would this just be a Simulator bug or have I done something wrong?
thanks!
I have created one file named dummy.html under the documents directory. Below is the working code snippet for downloading file. You can log path and see where its pointing. Use safari develop tool iOS simulator for inspecting. I have added file & filetransfer plugin.
function downloadFile() {
window.requestFileSystem(
LocalFileSystem.PERSISTENT, 0,
function onFileSystemSuccess(fileSystem) {
fileSystem.root.getFile(
"dummy.html", {
create: true,
exclusive: false
},
function gotFileEntry(fileEntry) {
console.log(fileEntry);
var sPath = fileEntry.nativeURL.replace("dummy.html", "");
console.log(sPath);
var fileTransfer = new FileTransfer();
fileEntry.remove();
fileTransfer.download(
"http://developer.android.com/assets/images/home/ics-android.png",
sPath + "dummy.png",
function(theFile) {
console.log("download complete: " + theFile.toURI());
showLink(theFile.toURI());
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code: " + error.code);
}
);
},
fail);
},
fail);
}
Check screenshot-
excellent! got it working.
Additionally found that not all files were problematic. Apple doesn't like custom file types nor file names with "%20" in them. Fixing all the above has worked!
My app needs to be bilingual (english and italian). I'm working on push notifications through cloud code and i'm trying to send different notifications based on the client language. I created a language field in the Installation table and saved to it the
[[NSLocale preferredLanguages] objectAtIndex:0];. The code below works but i wonder if there is another way to do it. I would prefer to set the "alert" message before the query so that i would have only 1 query. Basically i need to check if the language field for that particular user is "it" or not and then make the query. Is it possible or mine is the only solution?
//push test
Parse.Cloud.afterSave("MeetingObject", function(request) {
// user owner of the meeting object
var user = request.object.get("user");
var pushQueryEn = new Parse.Query(Parse.Installation);
pushQueryEn.equalTo("user", user);
pushQueryEn.notEqualTo("language", 'it');
Parse.Push.send({
where: pushQueryEn,
data: {
alert: "English push test",
badge: "Increment",
sound: "cheering.caf",
}
}, {
success: function() {
// Push was successful
console.log(request.object.get("language"));
},
error: function(error) {
console.error("Got an error " + error.code + " : " + error.message);
}
});
var pushQueryIt = new Parse.Query(Parse.Installation);
pushQueryIt.equalTo("user", user);
pushQueryIt.equalTo("language", 'it');
Parse.Push.send({
where: pushQueryIt,
data: {
alert: "Italian push test",
badge: "Increment",
sound: "cheering.caf",
}
}, {
success: function() {
// Push was successful
console.log(request.object.get("language"));
},
error: function(error) {
console.error("Got an error " + error.code + " : " + error.message);
}
});
});
Yes, there is. You have to set the aps dictionary of the push notification payload directly and use the loc-key and optionally the loc-args and action-loc-key parameters. In the first parameter you pass the localization key of the message that you have localized in your Localizable.strings file in your application bundle. In the second argument you can pass an array that will be substituted to the string placeholders in the localized message. The third argument will be used as the name of the default action ("slide to …")
For example you define in your Localizable.stings file the following key:
"msg" = "%# wants to send you a message";
"rsp" = "respond";
And in cloud code you construct your push payload as follows:
var payload =
"data":{
"aps":{
"alert":{
"loc-key":"msg",
"loc-args":["John"],
"action-loc-key":"rsp"
},
}
};
// set at least the 'where' key of the payload
Parse.Push.send(payload);
This code should show you "John wants to send you a message", localized to the current locale of the user and the default action would be "slide to respond…"