The following is my cloud code to send parse push notification:
Parse.Cloud.define('push1', function(response)
{
var query = new Parse.Query(Parse.Installation);
Parse.Push.send
({
where: query,
data:
{
alert: "Hai everyone..!!"
}
},
{
useMasterKey : true,
success: function()
{
response.success("true");
},
error: function(error)
{
response.error("error");
}
});
});
But the device from which I call this function only receives the notification. No other devices receives it. There are 3 devices added to the Installation class.
this is the app code from which I call this function
HashMap<String, Object> params = new HashMap<String, Object>();
ParseCloud.callFunctionInBackground("push1", params, new FunctionCallback<String>()
{
#Override
public void done(String ratings, ParseException e)
{
if (e == null)
{
System.out.println("WORKED: " + ratings);
}
else
System.out.println(e.toString());
}
});
Related
How do I get EventSource.onmessage to work?
Here is my subscribe and pushevent code:
public SseEmitter subscribe() throws Exception {
SseEmitter emitter = new SseEmitter(1800000L);
emitters.add(emitter);
emitter.onCompletion(() -> {
synchronized (emitters) {
emitters.remove(emitter);
}
});
emitter.onTimeout(() -> {
emitter.complete();
emitters.remove(emitter);
});
return emitter;
}
#Async
public void pushEventMap(Map<String, Object> pushMap) throws IOException {
List<SseEmitter> deadEmitters = new ArrayList<>();
HashMap<String,Object> map = (HashMap<String,Object>) pushMap;
emitters.forEach(emitter -> {
try {
emitter.send(SseEmitter.event().name("myEvent").data(map));
} catch (Exception e) {
emitter.completeWithError(e);
logger_error.error("pushEvent Exception:" + e);
deadEmitters.add(emitter);
}
});
emitters.removeAll(deadEmitters);
}
The controller for the above service is:
#RequestMapping(value = "/subscribe", produces = "text/event-stream")
public ResponseEntity<SseEmitter> subscribe() throws Exception {
final SseEmitter emitter = eventService.subscribe();
return new ResponseEntity<>(emitter, HttpStatus.OK);
}
#RequestMapping(value = "/publish")
public void publish() throws IOException {
eventService.pushEventMap(pushMap);
}
I want the client to receive the data of event push through js.
const eventInit = () => {
console.log("eventInit called");
const url = 'http://localhost:8080/itf/subscribe';
const eventSource = new EventSource(url);
var httpRequest = new XMLHttpRequest();
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('===');
console.log(data);
}
eventSource.onopen = (event) => {
console.log('sse open');
console.log(event);
}
eventSource.onerror = (event) => {
if (event.readyState == EventSource.CLOSED) {
console.log('sse close');
} else {
console.log("onerror", e);
}
}
}
In this state, if I send event-generating data through postman, sse open appears on the console.
However, the result of the event is not displayed.
If I directly access /itf/subscribe through the url, the result of the event is displayed on the screen. However, I am not receiving the result of the event through event.onmessage.
What I want is to raise an event, and then receive the result of the event through the onmessage function.
I am wondering how can I get the result of the event.
best regards
There is no issue with code, the actual issue is when I am writing response to client my response message should look like as below.
PrintWriter out = response.write("data: message"+value+"\n\n");
out.flush(); //don't forget to flush
In my code I was missing the last part "\n\n" in response object so source.onmessage(datalist) in javascript didn't get hit.
eventSource.addEventListener('myEvent', function (event) {
console.log(event);
const data = JSON.parse(event.data);
console.log('addEventListener');
console.log(data);
// console.log(data.siteCode);
eventEffect(data);
}, false);
this is normally work!
I'm writing a script using php to upload images to my local server.
user will upload the images from android application and I'm using retrofit library to do so. I want to return the path and name generated for the image in php for further processing in android. The problem is the php script always return an empty json
PHP Script
<?php
if (isset($_POST['image'])) {
$upload_folder = "Signatures"; // Name of the folder.
$unique_name = microtime().uniqid(); // Name of the image. use time method to make it unique.
$path = "$upload_folder/$unique_name.jpg";
$Image = $_POST['image'];
if (file_put_contents($path,base64_decode($Image)) != false) {
$data = [ 'imagePath' => $path];
header('Content-type: application/json');
echo json_encode( $data );
exit;
}
else {
$data = [ 'imagePath' => 'No image path'];
header('Content-type: application/json');
echo json_encode( $data );
exit;
}
}
else {
$data = [ 'imagePath' => 'No image path'];
header('Content-type: application/json');
echo json_encode( $data );
exit;
}
?>
Retorift method signature
#FormUrlEncoded
#POST ("Images.php")
Call<JSONObject> uploadImage (#Field("image") String image );
Upload image method
public void uploadImage(){
String image = imageToString(signatureView.getSignatureBitmap());
IAPI iAPI = Application.getImage();
Call<JSONObject> call = iAPI.uploadImage(image);
call.enqueue(new Callback<JSONObject>() {
#Override
public void onResponse(Call<JSONObject> call, Response<JSONObject> response) {
if (response.isSuccessful()) {
Log.d("test" , "is succ");
try {
JSONObject responseJSON = response.body();
Log.d("test" , responseJSON.toString());
String path = responseJSON.getString("path");
if (path == null) {
Log.d("test" , "path is null");
} else {
Log.d("test" , "path not null");
}
} catch (JSONException e) {
Log.d("test" , e.toString());
e.printStackTrace();
}
} else {
Log.d("test" , "not succ");
}
}
#Override
public void onFailure(Call<JSONObject> call, Throwable t) {
Log.d("test", " in onFailure - load image :" + t.getMessage() + t.toString());
}
});
}
It always throws an exception saying that there is no value for path.
And responseJSON.toString() in log prints empty [].
EDIT :
I have created my own model that contains property called imagePath and now it's wroking. Thank you all
I am using PHP as my API for a messaging android app, I have created a script which will register the user by inserting data into the database when logging for the first time, I have tried this Link but my primary key is unique and still the script is executing two times and which causes an error
:-
[27-Feb-2018 17:44:12 UTC] PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '3bc91dab47aeb989' for key 'users_device_id_uindex'' in [My Api Url]/DbFunction.php:44
Which means that there is a duplicate entry in the table.Basically, It stores the value perfectly when executed for the first time but when it executes again it gives the error described above
Script for registration (register.php):-
<?php
require_once ("DbFunction.php");//Importing DbFunction Class
/*Initializing Variables*/
$response = array();
$db = new DbFunction();
$result = $device_id = $phone_number = $user_name = $email = $website =
$profile_picture = $token = $created_at = '';
/* Checking If REQUEST_METHOD is POST*/
if($_SERVER['REQUEST_METHOD'] == 'POST') {
/*Checking is variables are set*/
$device_id = isset($_POST['device_id']) ? $_POST['device_id']:null;
$phone_number = isset($_POST['phone_number']) $_POST['phone_number']:null;
$user_name = isset($_POST['user_name']) ? $_POST['user_name'] : null;
$email = isset($_POST['email']) ? $_POST['email'] : null;
$website = isset($_POST['website']) ? $_POST['website'] : null;
$profile_picture = isset($_POST['profile_picture']) ? $_POST['profile_picture'] : null;
$token = isset($_POST['token']) ? $_POST['token'] : null;
$created_at = isset($_POST['created_at']) ? $_POST['created_at'] : null;
/* Checking For Nulls*/
if (!isNull($device_id) || !isNull($phone_number) || !isNull($user_name) || !isNull($email) || !isNull($profile_picture) || !isNull($token) || !isNull($created_at)) {
/* Calling The createUser functions with required parameters*/
$result = $db->createUser($device_id, $phone_number, $user_name, $email, $website, $profile_picture, $token, $created_at);
$response['error'] = !$result;// Setting the value of error which is inverse of $result(if result == true which means user registered successfully and there is no error so inverse of result which is false and vice versa)
if($result)
{
$response['message'] = "User Registered Successfully";
}
else{
$response['message'] = "Registration Error";
}
}
/* Echoing The Reponse*/
echo json_encode($response);
}
function isNull($variable)
{
return is_null($variable);
}
script for functions (DbFunction.php):-
public function createUser($device_id,$phone_number,$user_name ,$email ,$website ,$profile_dp ,$token ,$created_at )
{
/* Calling the uploadImage funtion to upload the Image To Server which will Return Url Where Image Is Stored*/
$profile_picture = $this->uploadImage($profile_dp, $email);
$stmt = $this->conn->prepare("INSERT INTO users (device_id, phone_number, user_name, email, website, profile_picture, token, created_at) VALUES (:device_id, :phone_number, :user_name, :email, :website, :profile_picture, :token, :created_at)");
$stmt->bindValue(':device_id', $device_id);
$stmt->bindValue(':phone_number', $phone_number);
$stmt->bindValue(':user_name', $user_name);
$stmt->bindValue(':email', $email);
$stmt->bindValue(':website', $website);
$stmt->bindValue(':profile_picture', $profile_picture);
$stmt->bindValue(':token', $token);
$stmt->bindValue(':created_at', $created_at);
return $stmt->execute();
}
And now the Android code from where I am calling the request, I am using volley for that.
UserInfoActivity.java :-
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnNext:
if (isValidInput()) {
sendDataToServer();
dialog.setMessage("Loading....");
dialog.show();
}
}
}
private void sendDataToServer() {
StringRequest strreq = new StringRequest(Request.Method.POST,
Config.URL_REGISTER,
new Response.Listener<String>() {
#Override
public void onResponse(String Response) {
dialog.dismiss();
Log.d(TAG, Response);
Boolean error = null;
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(Response);
error = jsonObject.getBoolean("error");
if(!error)
{
Toast.makeText(UserInfoActivity.this,"User Registered Successfully",Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(UserInfoActivity.this, "Something Went Wrong While Registering", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(UserInfoActivity.this, "Something Went Wrong While Registering", Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError e) {
VolleyLog.e(TAG, e);
e.printStackTrace();
Toast.makeText(UserInfoActivity.this, "Something Went Wrong While Registering", Toast.LENGTH_LONG).show();
dialog.dismiss();
}
}) {
#SuppressLint("HardwareIds")
#Override
public Map<String, String> getParams() {
DateTime dateTime = new DateTime();
SharedPreferences pref = getApplicationContext().getSharedPreferences(Config.SHARED_PREF, 0);
Map<String, String> params = new HashMap<>();
params.put("phone_number", FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber());
params.put("user_name", etName.getText().toString());
params.put("email", etEmail.getText().toString());
if (!TextUtils.isEmpty(etWebsite.getText().toString())) {
params.put("website", etWebsite.getText().toString());
}
params.put("token", pref.getString("token", null));
params.put("device_id", Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID));
params.put("created_at", dateTime.toString());
params.put("profile_picture", image_to_server);
return params;
}
};
AppSingleton.getInstance(UserInfoActivity.this).addToRequestQueue(strreq);
}
AppSingleton.java :-
public class AppSingleton {
private static AppSingleton mInstance;
private RequestQueue mRequestQueue;
private static Context mContext;
private AppSingleton(Context context){
// Specify the application context
mContext = context;
// Get the request queue
mRequestQueue = getRequestQueue();
}
public static synchronized AppSingleton getInstance(Context context){
// If Instance is null then initialize new Instance
if(mInstance == null){
mInstance = new AppSingleton(context);
}
// Return MySingleton new Instance
return mInstance;
}
public RequestQueue getRequestQueue(){
// If RequestQueue is null the initialize new RequestQueue
if(mRequestQueue == null){
mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
}
// Return RequestQueue
return mRequestQueue;
}
public<T> void addToRequestQueue(Request<T> request){
// Add the specified request to the request queue
getRequestQueue().add(request);
}
}
And after request, I get an error response which is null:-
02-28 14:58:20.690 14606-14606/com.dev.pigeon E/Volley: [1] 3.onErrorResponse: USERINFOACTIVITYTAG
UPDATE
After Watching the Log clearly I saw this:-
02-28 17:21:36.448 21212-21815/com.dev.pigeon D/Volley: [22348] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] http://[My Api Url]/register.php 0xec86a58c NORMAL 1> [lifetime=8562], [size=1208], [rc=500], [retryCount=1]
02-28 17:21:36.449 21212-21815/com.dev.pigeon E/Volley: [22348] BasicNetwork.performRequest: Unexpected response code 500 for http://[My APi Url]/register.php
02-28 17:21:36.463 21212-21212/com.dev.pigeon E/Volley: [1] 3.onErrorResponse: USERINFOACTIVITYTAG
Above Error Says That Volley Is Retrying The Request, I don't know why?
Please help from where this error is occurring, I am working on this weird behavior of Volley for a long time but didn't get any solution.
P.S. Sorry For My Bad English And Badly Written Code!!
I want to creat xml-rpc POST request, and pass 2 parameters "application_name" & "key", and change content type to "application/x-www-form-urlencoded" like my code below.
try {
XMLRPCClient oneTimeKeyClient = new XMLRPCClient(new URL(URL_REQUEST_SAMPLE), XMLRPCClient.FLAGS_DEFAULT_TYPE_STRING);
oneTimeKeyClient.setCustomHttpHeader("X-HTTP-METHOD-OVERRIDE", "POST");
// oneTimeKeyClient.setCustomHttpHeader("Content-Type", "application/x-www-form-urlencoded");
HashMap<String, String> oneTimeKeyParam = new HashMap<>();
oneTimeKeyParam.put("application_name", "hello_app");
oneTimeKeyParam.put("key", "bb5eb953d3b41dcf59f4669d98f8e14782ed83133be772956b");
Vector<Object> params = new Vector<Object>();
params.add(oneTimeKeyParam);
oneTimeKeyClient.callAsync(new XMLRPCCallback() {
#Override
public void onResponse(long id, Object response) {
try {
result = ((Map) response).get(NAME_ONE_TIME_KEY).toString();
} catch (Exception e) {
Timber.e("onParseError %s", e.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
}
#Override
public void onError(long id, XMLRPCException error) {
Timber.e("onError %s", error.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
#Override
public void onServerError(long id, XMLRPCServerException error) {
Timber.e("onServerError %s", error.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
}, "", params);
} catch (Exception e) {
Timber.e("onError %s", e.getMessage());
DialogUtil.showLoginErrorDialog(getSupportFragmentManager());
}
I got error " onServerError APPLICATION_NAME must record not exists."
I using aXMLRPC library https://github.com/gturri/aXMLRPC .
Which library do you recommend ?
Can I use Retrofit to make xml-rpc request ?
Thanks for any help
You just use retrofit like this:
#FormUrlEncoded
#POST("onetime_key")
Observable<OneTimeKeyRes> requestOneTimeKey(#Field("application_name") String applicationName, #Field("key") String key);
You must add SimpleXmlConverter:
Retrofit retrofit = new Retrofit.Builder()
.client(builder.build())
.baseUrl(YOUR_BASE_URL)
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
I'm building a system which has push notification feature and use Jersey to create API.
I read an article about comet approach and end up with the following code:
Index.js
function checkExamNotification() {
$.ajax({
url: contextPath + '/api/notification/checkExamNotification',
type: 'get',
data: {
accountId: accountId,
sessionId: sessionId
},
success: function (res) {
console.log("success");
displayNumberOfNotification();
checkExamNotification();
},
error: function (jqXHR, textStatus, errorThrown) {
if (textStatus === "timeout") {
checkExamNotification();
}
}
});
}
$(document).ready(function () {
$.ajaxSetup({
timeout: 1000*60*3
});
checkExamNotification();
});
Check exam notification API
#GET
#Path("/checkExamNotification")
public Response checkExamNotification(#QueryParam("accountId") int accountId, #QueryParam("sessionId") String sessionId) throws InterruptedException {
if (memCachedClient.checkSession(sessionId, accountId)) {
while (!examNotificationQueue.hasItems()) {
Thread.sleep(5000);
}
ExamNotificationQueueItemModel examNotificationQueueItemModel = examNotificationQueue.dequeue();
if (examNotificationQueueItemModel.getAccountId() == accountId) {
LOGGER.info("[START] Check exam notification API");
LOGGER.info("Account ID: " + accountId);
LOGGER.info("Get notification with exam ID: " + examNotificationQueueItemModel.getExamId());
ExamEntity exam = examDAO.findById(examNotificationQueueItemModel.getExamId());
NotificationEntity notification = notificationDAO.findByExamId(exam.getExamid());
notification.setSend(1);
notificationDAO.getEntityManager().getTransaction().begin();
notificationDAO.update(notification);
notificationDAO.getEntityManager().getTransaction().commit();
LOGGER.info("[END]");
String result = gson.toJson(examNotificationQueueItemModel);
return Response.status(200).entity(result).build();
} else {
examNotificationQueue.enqueue(examNotificationQueueItemModel);
Thread.sleep(5000);
checkExamNotification(accountId, sessionId);
}
}
return Response.status(200).entity(gson.toJson("timeout")).build();
}
From my debug, the API did finish return but the success event SOMETIMES didn't fire.
Yes, sometimes console log success but sometimes it doesn't.
Can anybody explain to me this case?
Thanks in advance. Any help would be appreciated.
Ok after following #peeskillet comment. Here is my finally code.
Check exam notification API
#GET
#Produces(SseFeature.SERVER_SENT_EVENTS)
#Path("/checkExamNotification")
public EventOutput checkExamNotification(#QueryParam("accountId") final int accountId, #QueryParam("sessionId") final String sessionId) {
final EventOutput eventOutput = new EventOutput();
if (memCachedClient.checkSession(sessionId, accountId)) {
new Thread(new Runnable() {
public void run() {
try {
if (examNotificationQueue.hasItems()) {
ExamNotificationQueueItemModel examNotificationQueueItemModel = examNotificationQueue.dequeue();
if (examNotificationQueueItemModel.getAccountId() == accountId) {
LOGGER.info("[START] Check exam notification API");
LOGGER.info("Account ID: " + accountId);
LOGGER.info("Get notification with exam ID: " + examNotificationQueueItemModel.getExamName());
String result = gson.toJson(examNotificationQueueItemModel);
final OutboundEvent.Builder eventBuilder
= new OutboundEvent.Builder();
eventBuilder.data(result);
final OutboundEvent event = eventBuilder.build();
eventOutput.write(event);
LOGGER.info("[END]");
} else {
examNotificationQueue.enqueue(examNotificationQueueItemModel);
}
}
} catch (IOException e) {
throw new RuntimeException(
"Error when writing the event.", e);
} finally {
try {
eventOutput.close();
} catch (IOException ioClose) {
throw new RuntimeException(
"Error when closing the event output.", ioClose);
}
}
}
}).start();
}
return eventOutput;
}
Index.js
function checkExamNotification() {
var url = contextPath + '/api/notification/checkExamNotification?accountId=' + accountId + '&sessionId=' + sessionId;
var source = new EventSource(url);
source.onmessage = function (event) {
displayNumberOfNotification();
};
}