Parse.com Receiving push notifications even if not subscribed to channel - android
i'm receiving push notifications even from channels i'm not subscribed to.
My app gets the user interest from a remote JSON and subscribe him to the channels in Parse.
I'll try to copy all the related code.
MyApplication.java
Parse.enableLocalDatastore(this);
Parse.initialize(this, ParseAppID, ParseClientKey);
ParseInstallation installation=ParseInstallation.getCurrentInstallation();
installation.put("UniqueId", android_id);
installation.saveInBackground();
MainActivity.java (inside an AsyncTask onPostExecute)
JSONObject jObject = new JSONObject(result);
int error = jObject.getInt("Error");
ArrayList<String> channels = new ArrayList<String>();
if(error==0){
JSONArray intereses = jObject.getJSONArray("Interests");
Log.d("ChannelsTrack", "Error: 0");
for(int j=0; j < intereses.length(); j++) {
int interes = intereses.getInt(j);
String channel_name="sdc_channel_" + interes;
channels.add(channel_name);
Log.d("ChannelsTrack", channel_name);
ParsePush.subscribeInBackground( channel_name );
}
List<String> subscribedChannels = ParseInstallation.getCurrentInstallation().getList("channels");
for(int j=0; j < subscribedChannels.size(); j++) {
if(!channels.contains(subscribedChannels.get(j))){
ParsePush.unsubscribeInBackground( subscribedChannels.get(j) );
}
}
}else{
Log.d("ChannelsTrack", "Error: " + error);
}
This is aparently working. I can see my Parse user subscribed to the specified channels y the console
I can't post images but, in Parse Core table it's a single row with ["sdc_channel_6","sdc_channel_5","sdc_channel_2","sdc_channel_3","sdc_channel_4"] in the "channels" column and it changes when i update the user interests so i think everything it's working at this point.
I'm using the REST API to send push notifications using this JSON
{
"data": {
"action": "my.application.UPDATE_STATUS",
"t": "Text",
"d": "Text 2",
"f": "",
"u": "http://example.com"
},
"where": {
"channels": {
"$in": ["sdc_channel_99","sdc_channel_88"]
},
"deviceType": "android"
}
}
And here is the problem. I receive the push notification sent to "sdc_channel_99" and "sdc_channel_88" channels but i'm not subscribed to them (and i've never been subscribed to them).
Obviously i'm missing something, any help? Thanks.
I think the problem is in your compound query :
"where": {
"channels": {
"$in": ["sdc_channel_99","sdc_channel_88"]
},
"$in" means "Contained In" so if the user is subscribed to channel "sdc_channel_9" and channel "sdc_channel_8", the user will be selected.
may be you should try this query :
"where" : {"$or":[{"channels":"sdc_channel_99"},{"channels":"sdc_channel_88"}]}
Related
Parse Nested JSON Array from Notification Data using Gson in Android
I am getting data in JSON format from FCM notification. It has different format based on notification types as below: Format 1: accept_request: { "alert": "Accept Request By driver", "title": "Accept Request By driver", "booking_id": "247", "notification_type": "accept_request" } Format 2: end_request: { "alert": "End trip By driver", "title": "End trip By driver", "booking_id": "247", "notification_type": "end_request", "servicesList": [ { "service_id": "1", "service_name": "Services1", "status": "true", "sub_category": [ { "sub_cat_id": "1", "sub_cat_name": "Doctors on call", "service_cost": "15.00", "service_cat_id": "1", "cost": 0 } ], "is_multiple_choose": "0", "total_cost": 15 } } I have create CommonNotificationBean.java as POJO class. I have successfully parsed data for accept_request. Its working because all key has String values and remoteMessage.getData() also returning Map<String, String> type values. Code: // Check if message contains a data payload. if (remoteMessage.getData().size() > 0) { Log.d(TAG, "Message data payload: " + remoteMessage.getData().get("notification_type")); Map<String, String> params = remoteMessage.getData(); JSONObject object = new JSONObject(params); Gson gson = new Gson(); JsonReader reader = new JsonReader(new StringReader(object.toString())); reader.setLenient(true); CommonNotificationBean bean = gson.fromJson(reader, CommonNotificationBean.class); sendNotification(bean); } PROBLEM: Now I am stuck with problem while parsing end_request data because it has Nested JSON Array. Read it carefully: What can I do for dynamic data instead of Map<String, String> because it will not convert data into Map<String, String> type as it has some List type values. Anyone can help?
And finally I got solution by adding some drops of concepts. :) I got many problems to converting in JSON with proper format like: Unterminated object at character MalformedJsonException and Finally following code get worked for me. if (remoteMessage.getData().size() > 0) { Log.d(TAG, "remoteMessage.getData() : " + remoteMessage.getData()); // Map<String, String> stringStringMap = remoteMessage.getData(); JSONObject object = new JSONObject(remoteMessage.getData()); Log.d(TAG, "new JSONObject(remoteMessage.getData()) : " + object.toString()); String finalJSON = object.toString().replaceAll("\\\\", "").replace("\"[", "[").replace("]\"", "]"); Log.d(TAG, "Replace all back slash and invalid double quotes : " + finalJSON); CommonNotificationBean bean = new Gson().fromJson(finalJSON, CommonNotificationBean.class); sendNotification(bean); } Logcat: remoteMessage.getData(): Getting data without double quotes. remoteMessage.getData() : {content-available=1, notification_type=end_request, booking_id=247, priority=high, base_price=35, totalMinutePrice=1.5, alert=End trip By driver, sound=default, title=End trip By driver, total_amount=397, address_from=A/ 4 forum bungalow Nr. Hicort, Sola, Ahmedabad, Gujarat 380015, India, service_cost=360, servicesList=[{"total_cost":15,"sub_category":[{"cost":0,"sub_cat_name":"Doctors on call","sub_cat_id":"1","service_cost":"15.00","service_cat_id":"1"}],"service_name":"Services1","service_id":"1","is_multiple_choose":"0","status":"true"},{"total_cost":95,"sub_category":[{"cost":0,"sub_cat_name":"Hand","sub_cat_id":"3","service_cost":"20.00","service_cat_id":"2"},{"cost":0,"sub_cat_name":"Body","sub_cat_id":"4","service_cost":"75.00","service_cat_id":"2"}],"service_name":"Dressing","service_id":"2","is_multiple_choose":"1","status":"true"},{"total_cost":0,"sub_category":[{"cost":0,"sub_cat_name":"No","sub_cat_id":"7","service_cost":"0.00","service_cat_id":"3"}],"service_name":"Do you need oxygen?","service_id":"3","is_multiple_choose":"0","status":"true"},{"total_cost":30,"sub_category":[{"cost":0,"sub_cat_name":"Level 3","sub_cat_id":"10","service_cost":"30.00","service_cat_id":"4"}],"service_name":"Lift\/Stairs Accessibility","service_id":"4","is_multiple_choose":"0","status":"true"},{"total_cost":220,"sub_category":[{"cost":0,"sub_cat_name":"Ventilator","sub_cat_id":"12","service_cost":"100.00","service_cat_id":"5"},{"cost":0,"sub_cat_name":"Intracenous (IV) drip","sub_cat_id":"13","service_cost":"120.00","service_cat_id":"5"}],"service_name":"Other Medical","service_id":"5","is_multiple_choose":"1","status":"true"},{}], tripdatetime=2019-03-27 10:57:51, address_to=19/20, Chanakyapuri, Ahmedabad, Gujarat 382481, India, notification_date_time=28-03-2019 17:24:09} new JSONObject(remoteMessage.getData()) : Converted to JSONObject but getting unwanted back slash and double quotes new JSONObject(remoteMessage.getData()) : {"content-available":"1","notification_type":"end_request","booking_id":"247","priority":"high","base_price":"35","totalMinutePrice":"1.5","alert":"End trip By driver","sound":"default","title":"End trip By driver","total_amount":"397","address_from":"A\/ 4 forum bungalow Nr. Hicort, Sola, Ahmedabad, Gujarat 380015, India","service_cost":"360","servicesList":"[{\"total_cost\":15,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Doctors on call\",\"sub_cat_id\":\"1\",\"service_cost\":\"15.00\",\"service_cat_id\":\"1\"}],\"service_name\":\"Services1\",\"service_id\":\"1\",\"is_multiple_choose\":\"0\",\"status\":\"true\"},{\"total_cost\":95,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Hand\",\"sub_cat_id\":\"3\",\"service_cost\":\"20.00\",\"service_cat_id\":\"2\"},{\"cost\":0,\"sub_cat_name\":\"Body\",\"sub_cat_id\":\"4\",\"service_cost\":\"75.00\",\"service_cat_id\":\"2\"}],\"service_name\":\"Dressing\",\"service_id\":\"2\",\"is_multiple_choose\":\"1\",\"status\":\"true\"},{\"total_cost\":0,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"No\",\"sub_cat_id\":\"7\",\"service_cost\":\"0.00\",\"service_cat_id\":\"3\"}],\"service_name\":\"Do you need oxygen?\",\"service_id\":\"3\",\"is_multiple_choose\":\"0\",\"status\":\"true\"},{\"total_cost\":30,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Level 3\",\"sub_cat_id\":\"10\",\"service_cost\":\"30.00\",\"service_cat_id\":\"4\"}],\"service_name\":\"Lift\\\/Stairs Accessibility\",\"service_id\":\"4\",\"is_multiple_choose\":\"0\",\"status\":\"true\"},{\"total_cost\":220,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Ventilator\",\"sub_cat_id\":\"12\",\"service_cost\":\"100.00\",\"service_cat_id\":\"5\"},{\"cost\":0,\"sub_cat_name\":\"Intracenous (IV) drip\",\"sub_cat_id\":\"13\",\"service_cost\":\"120.00\",\"service_cat_id\":\"5\"}],\"service_name\":\"Other Medical\",\"service_id\":\"5\",\"is_multiple_choose\":\"1\",\"status\":\"true\"},{}]","tripdatetime":"2019-03-27 10:57:51","address_to":"19\/20, Chanakyapuri, Ahmedabad, Gujarat 382481, India","notification_date_time":"28-03-2019 17:24:09"} Final JSON : Replace all back slash and invalid double quotes : {"content-available":"1","notification_type":"end_request","booking_id":"247","priority":"high","base_price":"35","totalMinutePrice":"1.5","alert":"End trip By driver","sound":"default","title":"End trip By driver","total_amount":"397","address_from":"A/ 4 forum bungalow Nr. Hicort, Sola, Ahmedabad, Gujarat 380015, India","service_cost":"360","servicesList":[{"total_cost":15,"sub_category":[{"cost":0,"sub_cat_name":"Doctors on call","sub_cat_id":"1","service_cost":"15.00","service_cat_id":"1"}],"service_name":"Services1","service_id":"1","is_multiple_choose":"0","status":"true"},{"total_cost":95,"sub_category":[{"cost":0,"sub_cat_name":"Hand","sub_cat_id":"3","service_cost":"20.00","service_cat_id":"2"},{"cost":0,"sub_cat_name":"Body","sub_cat_id":"4","service_cost":"75.00","service_cat_id":"2"}],"service_name":"Dressing","service_id":"2","is_multiple_choose":"1","status":"true"},{"total_cost":0,"sub_category":[{"cost":0,"sub_cat_name":"No","sub_cat_id":"7","service_cost":"0.00","service_cat_id":"3"}],"service_name":"Do you need oxygen?","service_id":"3","is_multiple_choose":"0","status":"true"},{"total_cost":30,"sub_category":[{"cost":0,"sub_cat_name":"Level 3","sub_cat_id":"10","service_cost":"30.00","service_cat_id":"4"}],"service_name":"Lift/Stairs Accessibility","service_id":"4","is_multiple_choose":"0","status":"true"},{"total_cost":220,"sub_category":[{"cost":0,"sub_cat_name":"Ventilator","sub_cat_id":"12","service_cost":"100.00","service_cat_id":"5"},{"cost":0,"sub_cat_name":"Intracenous (IV) drip","sub_cat_id":"13","service_cost":"120.00","service_cat_id":"5"}],"service_name":"Other Medical","service_id":"5","is_multiple_choose":"1","status":"true"},{}],"tripdatetime":"2019-03-27 10:57:51","address_to":"19/20, Chanakyapuri, Ahmedabad, Gujarat 382481, India","notification_date_time":"28-03-2019 17:24:09"} Full code : MyFirebaseMessagingService.java Hope it will be help to others.
It is simple, you should just have an abstract Notification object with the attributes alert, title and notification_type. And then, have specific implementations based on your possible types, so far: AcceptRequestNotification extends Notification with just an int booking_id (this is the one you already have, the one you called CommonNotificationBean) EndRequestNotification extends Notification which contains for example, an ArrayList called servicesList, this ArrayList should be of type Service and then, service would have the attributes: service_id, service_name, status, sub_category which is again another ArrayList of a custom type. And then you just change your code to be: // Check if message contains a data payload. if (remoteMessage.getData().size() > 0) { Log.d(TAG, "Message data payload: " + remoteMessage.getData().get("notification_type")); Map<String, String> params = remoteMessage.getData(); JSONObject object = new JSONObject(params); Gson gson = new Gson(); JsonReader reader = new JsonReader(new StringReader(object.toString())); reader.setLenient(true); Class typeOf; switch(remoteMessage.getData().get("notification_type")) { case "accept_request": typeOf = AcceptRequestNotification.class; break; case "end_request": typeOf = EndRequestNotification.class; break; } //you can cast this object later on (to the corresponding custom subclass of Notification), based on the notif.getNotificationType() value. Notification notif = gson.fromJson(reader, typeOf); sendNotification(notif); }
check if a Json file is modified or new item is added programmatically
I have a JSON file on my server with some data: This is some part of my JSON: { "ringtones": [ { "title": "Morning Alarm - Fur Elise", "link": "http://symphonyrecords.ir/rings/ala8_morning_alarm.mp3", "duration": "00:23", "id": 71, "genre": ["piano", "alarm"] }, { "title": "Moein - Tolou", "link": "http://symphonyrecords.ir/rings/pia1_moein_tolou.mp3", "duration": "00:43", "id": 70, "genre": ["piano"] } ] } I show this information in a list view, So first I download and save this JSON file in a temp folder, and then I populate my list with the downloaded file. This is how I get my JSON data JSONArray jsonArray = jsonObj.getJSONArray("ringtones"); for (int i = 0; i < jsonArray.length(); i++) { JSONObject obj = jsonArray.getJSONObject(i); Product product = new Product(); product.setTitle(obj.getString("title")); product.setThumbnailUrl(obj.getString("link")); product.setDuration(obj.getString("duration")); product.setId(obj.getInt("id")); JSONArray genreArray = obj.getJSONArray("genre"); ArrayList<String> genre = new ArrayList<>(); for (int j = 0; j < genreArray.length(); j++) { genre.add((String) genreArray.get(j)); } product.setGenre(genre); songList.add(product); I don't want to push notification remotely|manually every time I add a new item in my JSON, So I need to programmatically check whenever a new item is added and show notification locally. I've prepared my notification method. but I have no idea how to do the check. Can you give me a hint, please?
Since every ringtone objects in the JSON contains an ID, you can keep a cache of the existing IDs and do check against that whenever you want or show notification locally whenever that cache is changed.
JSON - no value for x
On Android, I am retrieving a JSON object via the following method; JSONObject tempObj = jsonObj.getJSONArray("result"); In order to be sure it comes properly, I system out it; System.out.println(tempObj); And it gives the following output; { "result": [ { "telMobile": "5555555", "products": [ { "id": "113245", "price": "749.0", "unitId": 1 }, { "id": "52589", "price": "7.35", "unitId": 1 } ] } ] } So, the JSONObject tempObj has a JSONArray named "products" inside, and each product has three fields named "id", "price" and "unitId". However, when I parse this object, I receive a "no value for unitId" error. for (int k = 0; k < tempObj.getJSONArray("products").length(); k++) { JSONObject tempProduct = tempObj.getJSONArray("products").getJSONObject(k); products.add(new Product(tempProduct.getString("id"), tempProduct.getString("price"),tempObj.getInt("unitId"))); } This is totally senseless. I can obtain the other fields properly. That means when I don't retrieve the unitId and write 1 instead; for (int k = 0; k < tempObj.getJSONArray("products").length(); k++) { JSONObject tempProduct = tempObj.getJSONArray("products").getJSONObject(k); products.add(new Product(tempProduct.getString("id"), tempProduct.getString("price"),1)); } Then the object is constructed properly. I tried getting it as a String then converting to int as; Integer.parseInt(tempProduct.getString("unitId")); However unitId still gives error. I would think that there would be a problem on the server side but the JSONObject arrives properly since I can see it from logcat output. This is a simple integer how can it cause such an arror? Could there be lying some different problems behind such a case?
You should change tempObj.getInt("unitId") to tempProduct.getInt("unitId") Actually you're trying to get value from tempObj. That is wrong. There is no value. so instead of get value from tempProduct
unitId is part of tempProduct not of tempObj. Change tempObj.getInt("unitId"))) with tempProduct.getInt("unitId")))
Get json array length and looping
So I have a json response from web service like this { error: false types: [2] -0: { card_type_id: 5 category: "Food & Beverages" } -1: { card_type_id: 8 category: "Entertaiment" } } what I want to do is to get the number inside json array "types" and use it to looping to set the value of arraylist that will be use in listview, but my code seems and cannot get the json array length, this is my code JSONObject obj = new JSONObject(response); if(!obj.getBoolean("error")){ JSONArray types = obj.getJSONArray("types"); for(int i=0; i<types.length();i++) { JSONObject a = types.getJSONObject(i); int ct_id = a.getInt("card_type_id"); String category = a.getString("category"); CardType ct = new CardType(); ct.setTypeId(_ct_id); ct.setTypeCategory(_category); categoryArray.add(ct); } } Can anyone help me? Thanks before
This is what your JSON response probably should look like (note also that keys and string values should be sorrounded by double-quotes): { "error": false, "types": [ { "card_type_id": 5, "category": "Food & Beverages" }, { "card_type_id": 8, "category": "Entertaiment" } ] } The JSONArray "types" in this example has a length (types.length()) of 2. Now you can implement your for-loop and should get the expected results.
actually it's just my fault to see the json from advanced rest client, i use the json menu and the app automatically correct the json and become invalid, after i change to raw menu i can see the actual json and correct the code
Android GCM: Can we get data as a complete JSON structure?
I am sending a message (POST) to Google GCM server https://android.googleapis.com/gcm/send for sending a push notification to a registered android device. The POST body looks something like this: { "registration_ids" : [android_registration_id], "data" : { "message" : "Hello World!", "update" : "You've got a new update", "info" : "You've got new information updates too!" } } Suppose that I don't know what all key-value pairs are being sent to me (gcm registered android app) in the "data" field and I want to enumerate and print them, can I extract the fields in "data" as a JSON structure? For e.g. In the above example, I need the following as a JSON object: { "message" : "Hello World!", "update" : "You've got a new update", "info" : "You've got new information updates too!" }
Bundle data = intent.getExtras(); Iterator<String> it = data.keySet().iterator(); String key; String value; while(it.hasNext()) { key = it.next(); value = data.getString(key); } Try this. Using key and value you can construct initial json.
JSONArray array = new JSONArray(jsonBodyOfTheResponse); for (int i = 0; i < array.length(); i++) { JSONObject row = array.getJSONObject(i); . . . }