PubNub Server does not format message properly - php

I have the server configuration to speak to the Android clients as:
<?php
require_once("mysql.class.php");
require_once("lib/autoloader.php");
// Setting up the PubNub Server:
use Pubnub\Pubnub;
$pubnub = new Pubnub(
"pub-c...", ## PUBLISH_KEY
"sub-c..." ## SUBSCRIBE_KEY
);
// Publishing :
$post_data = json_encode(array("type"=> "groupMessage", "data" => array("chatUser" => "SERVER", "chatMsg" => "Now lets talk", "chatTime"=>1446514201516)));
$info = $pubnub->publish('MainChat', $post_data);
print_r($info);
print_r($post_data);
?>
and html:
<!doctype html>
<html>
<head>
<title>PubNub PHP Test Page</title>
</head>
<body>
<form method="POST" action="index.php">
<input type="submit" name="submit" value="TestSendMessage" />
</form>
</body>
</html>
The publish function works in the server as I can see the messages arrive in the log console of the client Android app, but the message is never parsed correctly and therefore does not appear in the listview given the SubscribeCallback:
public void subscribeWithPresence(String channel) {
this.channel = channel;
Callback subscribeCallback = new Callback() {
#Override
public void successCallback(String channel, Object message) {
if (message instanceof JSONObject) {
try {
JSONObject jsonObj = (JSONObject) message;
JSONObject json = jsonObj.getJSONObject("data");
final String name = json.getString(Constants.JSON_USER);
final String msg = json.getString(Constants.JSON_MSG);
final long time = json.getLong(Constants.JSON_TIME);
if (name.equals(mPubNub.getUUID())) return; // Ignore own messages
final ChatMessage chatMsg = new ChatMessage(name, msg, time);
presentActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
// Adding messages published to the channel
mChatAdapter.addMessage(chatMsg);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
Log.d("PUBNUB", "Channel: " + channel + " Msg: " + message.toString());
}
#Override
public void connectCallback(String channel, Object message) {
Log.d("Subscribe", "Connected! " + message.toString());
//hereNow(false);
// setStateLogin();
}
};
try {
mPubNub.subscribe(this.channel, subscribeCallback);
//presenceSubscribe();
} catch (PubnubException e) {
e.printStackTrace();
// Checking if success
Log.d("Fail subscribe ", "on channel: " + channel);
}
}
Testing the server output in the browser by clicking TestSendMessage yields:
Array ( [0] => 1 [1] => Sent [2] => 14465159776373950 ) {"type":"groupMessage","data":{"chatUser":"SERVER","chatMsg":"Now lets talk","chatTime":1446514201516}}
and in app the log output from line: Log.d("PUBNUB", "Channel: " + channel + " Msg: " + message.toString());
Returns: D/PUBNUB: Channel: MainChat Msg: {"type":"groupMessage","data":{"chatUser":"SERVER","chatMsg":"Now lets talk","chatTime":1446514201516}}
as it should, but the message never appears within the ListView of messages and thusly fails the JSON parsing.
The JSON tags are straightforward from the Constants class as:
public static final String JSON_GROUP = "groupMessage";
public static final String JSON_USER = "chatUser";
public static final String JSON_MSG = "chatMsg";
public static final String JSON_TIME = "chatTime";
How can the server sending be reconfigured to allow the success of in app parsing?

Sending JSON over PubNub
Send the JSON object without stringifying it first. In the case for PHP, do not json_encode the message. PubNub SDK will encode and decode it for you.
This:
$post_data = array("type"=> "groupMessage", "data" => array(
"chatUser" => "SERVER", "chatMsg" => "Now lets talk",
"chatTime"=>1446514201516));
Not this:
$post_data = json_encode(array("type"=> "groupMessage", "data" => array(
"chatUser" => "SERVER", "chatMsg" => "Now lets talk",
"chatTime"=>1446514201516)));
Please comment if this resolves or not.

Related

Php Firebase verification with Twitter get user information

I wan't to implement a Twitter login through the Firebase API.
My client is a android app who loggs into the Twitter account and sends the IdToken to my php backend. This works fine.
OAuthProvider.Builder provider = OAuthProvider.newBuilder("twitter.com");
provider.addCustomParameter("lang", "de");
FirebaseAuth.getInstance()
.startActivityForSignInWithProvider(/* activity= */ this, provider.build())
.addOnSuccessListener(
new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
// User is signed in.
// IdP data available in
// authResult.getAdditionalUserInfo().getProfile().
// The OAuth access token can also be retrieved:
// authResult.getCredential().getAccessToken().
// The OAuth secret can be retrieved by calling:
// authResult.getCredential().getSecret().
Log.d("werte", "User is signed in");
Log.d("werte", "Username: " + authResult.getAdditionalUserInfo().getUsername());
Log.d("werte", "Info: " + authResult.getAdditionalUserInfo().getProfile().toString());
authResult.getUser().getIdToken(true).addOnSuccessListener(new OnSuccessListener<GetTokenResult>() {
#Override
public void onSuccess(GetTokenResult getTokenResult) {
Log.d("werte", "Accesstoken: " + getTokenResult.getToken());
}
});
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// Handle failure.
Log.d("werte", "Sign in failed");
e.printStackTrace();
}
});
But for php I only found a method to verify the token. I additionally need the user information. How do I get this?
$verifier = IdTokenVerifier::createWithProjectId('myProjectId');
try {
$token = $verifier->verifyIdToken($idToken);
echo($token);
} catch (IdTokenVerificationFailed $e) {
echo $e->getMessage();
// Example Output:
// The value 'eyJhb...' is not a verified ID token:
// - The token is expired.
}
Edit:
I solved it with the help of Frank. But I used a little different way.
$googleKeysURL = 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com';
$key = json_decode(file_get_contents($googleKeysURL), true);
$decoded = JWT::decode($idToken, $key, array("RS256"));
In the $decoded Object you can find every profile information you need.
Thank you Frank
Verifying the ID token does nothing more then what its name says: it verifies that the token is signed with a valid key.
If you want to use the claims from the decoded token, use a JWT decoding library like the one from Firebase: php-jwt. From the example in the documentation, you should be able to get the decoded token with:
$decoded = JWT::decode($jwt, $key, array('HS256'));

Checksum mismatch error paytm payment integration

I am trying to implement Paytm payment gateway in my app but it is giving
Bundle[{STATUS=TXN_FAILURE, ORDERID=order1, TXNAMOUNT=7.00, MID=cdBOMy65033449597261, RESPCODE=330, BANKTXNID=, CURRENCY=INR, RESPMSG=Paytm checksum mismatch.}] this error, for both TEST and Production environment.
Here is my PHP code to generate the checksum.
$paytmParams = array();
$paytmParams["MID"] = "cdBOMy65033449597261";
$paytmParams["ORDER_ID"] = "order1";
$paytmParams["CUST_ID"] = "cust1";
$paytmParams["MOBILE_NO"] = "9799990168";
$paytmParams["EMAIL"] = "droidwithme#gmail.com";
$paytmParams["CHANNEL_ID"] = "WAP";
$paytmParams["TXN_AMOUNT"] = "7.00";
$paytmParams["WEBSITE"] = "DEFAULT"; //tried WEBSTAGING and APPSTAGING
$paytmParams["INDUSTRY_TYPE_ID"] = "Retail";
$paytmParams["CALLBACK_URL"] = "https://securegw.paytm.in/theia/paytmCallback?ORDER_ID=order1";
//Here checksum string will return by getChecksumFromArray() function.
$paytmChecksum = EndecPaytm::getChecksumFromArray($paytmParams, $merchantKey);
$responseBody = [
'message' => 'Checksum Generated.',
'data' => [
"CHECKSUMHASH" => $paytmChecksum,
"ORDER_ID" => "order1",
"payt_STATUS" => "1"
]
];
return ApiMethods::apiResponse('success', $responseBody);
And this is my android side code,
private void getPaytmWindow(String chkSm) {
PaytmPGService Service = PaytmPGService.getProductionService();
//Kindly create complete Map and checksum on your server-side and then put it here in paramMap.
HashMap<String, String> paramMap = new HashMap<>();
paramMap.put( "MID" , "cdBOMy65033449597261"); //cdBOMy65033449597261
// Key in your staging and production MID available in your dashboard
paramMap.put( "ORDER_ID" , "order1");
paramMap.put( "CUST_ID" , "cust1");
paramMap.put( "MOBILE_NO" , "9799990168");
paramMap.put( "EMAIL" , "droidwithme#gmail.com");
paramMap.put( "CHANNEL_ID" , "WAP");
paramMap.put( "TXN_AMOUNT" , "7.00");
paramMap.put( "WEBSITE" , "DEFAULT");
// This is the staging value. Production value is available in your dashboard
paramMap.put( "INDUSTRY_TYPE_ID" , "Retail");
// This is the staging value. Production value is available in your dashboard
paramMap.put( "CALLBACK_URL", "https://securegw.paytm.in/theia/paytmCallback?ORDER_ID=order1");
paramMap.put( "CHECKSUMHASH" , chkSm);
PaytmOrder Order = new PaytmOrder(paramMap);
Service.initialize(Order, null);
Service.startPaymentTransaction(this, true, true,
new PaytmPaymentTransactionCallback() {
#Override
public void someUIErrorOccurred(String inErrorMessage) {
// Some UI Error Occurred in Payment Gateway Activity.
// // This may be due to initialization of views in
// Payment Gateway Activity or may be due to //
// initialization of webview. // Error Message details
// the error occurred.
Utils.logD(TAG, "someUIErrorOccurred : " + inErrorMessage);
}
#Override
public void onTransactionResponse(Bundle inResponse) {
Log.d("LOG123444", "Payment Transaction : " + inResponse);
if (Objects.requireNonNull(inResponse.getString("STATUS")).contains("TXN_SUCCESS")) {
Toast.makeText(getApplicationContext(), "Transaction completed", Toast.LENGTH_LONG).show();
}
Utils.logD(TAG, inResponse.getString("STATUS"));
// Toast.makeText( getApplicationContext(), "Payment Transaction response " + inResponse.toString(), Toast.LENGTH_LONG ).show();
}
#Override
public void networkNotAvailable() {
// If network is not
// available, then this
// method gets called.
}
#Override
public void clientAuthenticationFailed(String inErrorMessage) {
// This method gets called if client authentication
// failed. // Failure may be due to following reasons //
// 1. Server error or downtime. // 2. Server unable to
// generate checksum or checksum response is not in
// proper format. // 3. Server failed to authenticate
// that client. That is value of payt_STATUS is 2. //
// Error Message describes the reason for failure.
Utils.logD(TAG, "clientAuthenticationFailed " + inErrorMessage);
}
#Override
public void onErrorLoadingWebPage(int iniErrorCode,
String inErrorMessage, String inFailingUrl) {
Utils.logD(TAG, "inErrorMessage " + inErrorMessage);
Utils.logD(TAG, "inFailingUrl " + inFailingUrl);
}
// had to be added: NOTE
#Override
public void onBackPressedCancelTransaction() {
// TODO Auto-generated method stub
}
#Override
public void onTransactionCancel(String inErrorMessage, Bundle inResponse) {
Utils.logD(TAG, "Payment Transaction Failed " + inErrorMessage);
Toast.makeText(getBaseContext(), "Payment Transaction Failed ", Toast.LENGTH_LONG).show();
}
});
}
This is the Gradle dependency
implementation('com.paytm:pgplussdk:1.2.3') {
transitive = true
}
I have tried the Test environment and Production as well, but getting the checksum mismatch error every time.
For testing purposes, I have set the values hardcoded. I have gone various threads over the Paytm QA forum but they did not provide any sufficient answer to the threads(threads same as mine).
In PHP
Change this
$paytmParams["ORDER_ID"] = "order1";
to this
$paytmParams["ORDERID"] = "order1";
In APP
Change this
paramMap.put( "ORDER_ID" , "order1");
to this
paramMap.put( "ORDERID" , "order1");

Android / Loopj - How can i POST a complex JSON object to a server?

In one of my application, in which I use the Loopj library, I need to send a complex object to a web-service (running on PHP). I decided to send a JSON object via HTTP POST request using Loppj example.
JSONObject params = new JSONObject();
try
{
params.put("params1", "value1");
params.put("params2", "value2");
params.put("params3", "value3");
}
catch(JSONException e)
{
// ...
}
StringEntity entity = new StringEntity(params.toString(), HTTP.UTF_8);
ArrayList<Header> array = new ArrayList<>();
array.add(new BasicHeader("Content-type", "application/json"));
array.add(new BasicHeader("Accept", "application/json"));
Header[] headers = new Header[headers.size()];
headers = headers.toArray(array);
AsyncHttpClient client = new AsyncHttpClient();
client.post(context, url, headers, entity, "application/json", new JsonHttpResponseHandler()
{
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response)
{
//...
}
#Override
public void onFailure(int statusCode, Header[] headers, Throwable e, JSONObject errorResponse)
{
// ...
}
});
Unfortunately, $_POST / $_REQUEST are always empty. I've searched different tips but none of them is working. I haven't restriction on routes in my web-service, just a simple function to dump posted parameters.
EDIT 1
To check posted parameters, I coded a simple PHP page to log them. Thanks to #Steve, I was abble to find them in php://input.
file_put_contents(__DIR__ . '/post_data.log', json_encode($_POST));
file_put_contents(__DIR__ . '/input_data.log', file_get_contents('php://input'));
The fact is that I'm not the owner of the final web-services, so I can't change access to data. They must be accessible through $_POST. So, sending application/json isn't the solution ? How AJAX can send complex objects to a server and find them in $_POST, and not Android ?
EDIT 2
I tried to do the same with PostMan and $_POST is always empty. So, I analyzed the request sent by jQuery.ajax(...) (which allow you to send JSON object) and it generate proper key/value from JSON object.
For example, the JSON object :
{
"users":[
{
"name":"jean",
"age":"25",
"city":"paris"
}
]
}
It is converted in 3 pairs key/value :
users[0][name] : jean
users[0][age] : 25
users[0][city] : paris.
So, I guess I need a function which convert my JSONObject into RequestParams object and send it "normally" through "x-www-form-urlencoded". I don't know if there's any native function which can do this but I found the Javascript equivalent (Query-string encoding of a Javascript Object).
serialize = function(obj, prefix) {
  var str = [], p;
  for(p in obj) {
    if (obj.hasOwnProperty(p)) {
      var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
      str.push((v !== null && typeof v === "object") ?
        serialize(v, k) :
        encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
  }
  return str.join("&");
}
As I said previously, I wrote a helper class which convert JSONObject to RequestParams which can "normally" be sent over POST HTTP method.
I copy/paste it and wrote a quick README file. If you have any suggestions or even pull-requests, please share.
Hope it helps.
https://github.com/schnapse/json-to-requestparams

Unable to send notification to multiple devices using FCM

I'm getting a notification only in one device that is set as the first token stored the table in mySQL DB and the notification is not sent to the rest of the token numbers. I tried a WHILE loop and stored the token numbers in an array, but it did not work.
Please suggest a solution. Thank you.
Here is my code:
<?php
require "init.php";
$message=$_POST['message'];
$title=$_POST['title'];
$path_to_fcm='https://fcm.googleapis.com/fcm/send';
$server_key="A*************************Q";
$sql="select token from fcm_info";
$result =mysqli_query($con,$sql);
$row=mysqli_fetch_row($result);
$key=$row[0];
$headers = array(
'Authorization:key=' .$server_key,
'Content-Type:application/json'
);
$fields =array('to'=>$key,
'notification'=>array('title'=>$title,'body'=>$message));
$payload =json_encode($fields);
$curl_session =curl_init();
curl_setopt($curl_session,CURLOPT_URL, $path_to_fcm);
curl_setopt($curl_session,CURLOPT_POST, true);
curl_setopt($curl_session,CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl_session,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl_session,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_session,CURLOPT_IPRESOLVE, CURLOPT_IPRESOLVE);
curl_setopt($curl_session,CURLOPT_POSTFIELDS, $payload);
$result=curl_exec($curl_session);
curl_close($curl_session);
mysqli_close($con);
?>
Use 'registration_ids' instead of 'to' and pass comma separated multiple registrations ids to use multicast in FCM. Final payload should be like:
{
"registration_ids":["id1","id2",...],
"priority" : "normal",
"data" : {
"title" : "Title",
"message" : "Message to be send",
"icon": "icon_path"
}
}
see https://developers.google.com/cloud-messaging/http-server-ref for more help
////////////////////// FCM START /////////////////////////
$path_to_fcm = "https://fcm.googleapis.com/fcm/send";
$server_key = "your_server_key";
$headers = array(
'Authorization:key=' . $server_key,
'Content-Type:application/json');
$keys = ["key_1", "key_2"];
$fields = array(
"registration_ids" => $keys,
"priority" => "normal",
'notification' => array(
'title' => "title of notification",
'body' => "your notification goes here"
)
);
$payload = json_encode($fields);
$curl_session = curl_init();
curl_setopt($curl_session, CURLOPT_URL, $path_to_fcm);
curl_setopt($curl_session, CURLOPT_POST, true);
curl_setopt($curl_session, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl_session, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_session, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_session, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($curl_session, CURLOPT_POSTFIELDS, $payload);
$curl_result = curl_exec($curl_session);
////////////////////// FCM END /////////////////////////
This works for me.
You need to cover the notification sending logic in method and then start the loop & call that method in each iterations pass token and message to the method.
"Please suggest a solution"
I would like to suggest using Services. You're most recommended to read the documention by Android Studio here.
There is a lot to perceive about Services, but at the moment I believe a snippet will be most helpful to you, here is a little code,
Create a class called HelloService
and paste the following code inside with the proper imports*
public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
#Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "servicestarting",Toast.LENGTH_SHORT).show();
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
#Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
"This is overhwleming" you might think to yourself. However it's but the contrary.
Example for Services + Firebase
Instead of pushing a message from Firebase, let's say you want to notify a user whenever a modification takes place in one of your databases
first, create databasereference earlier on the Oncreate
mDatabaseLike=FirebaseDatabase.getInstance().getReference().child("Likes");
Go to 'handleMessage Method' and add the following
#Override
public void handleMessage(Message msg) {
mDatabaseLike.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
notifyUserOfDBupdate()
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
//stopSelf(msg.arg1);
}
}
Here is the notifyUserOfDBupdate method and how to notify a user
private void notifyUserOfDBupdate() {
//Intents
Intent Pdf_view = new Intent(this, //class to throw the user when they hit on notification\\.class);
PendingIntent pdf_view = PendingIntent.getActivity(this, 0, Pdf_view, 0);
//Notification Manager
NotificationManager nm = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
//The note
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification noti = new NotificationCompat.Builder(getApplicationContext())
.setTicker("TickerTitle")
.setContentTitle("content title")
.setSound(soundUri)
.setContentText("content text")
.setContentIntent(pdf_view).getNotification();
//Execution
noti.flags = Notification.FLAG_AUTO_CANCEL;
nm.notify(0, noti);
}
Now run your application once on your real device and a second time on an emulator. Once either one of two modifies your firebase database, the other will be notified instantly.
Modify whichever method you like inside the HandleMessage method. It will be eternal, not unless you make it killable.
kindest regards

WSDL/Soap web service response complex array parsing using KSOAP2 library

I have created PHP web service using nusoap
$namespace="http:/mynamespace.com/mynamespace"
$server = new soap_server();
$server->debug_flag = false;
$server->configureWSDL("test", $namespace);
$server->wsdl->schemaTargetNamespace = $namespace;
$server->wsdl->addComplexType(
'Products',
'complexType',
'struct',
'all',
'',
array('ID' => array('name' => 'ID','type' => 'xsd:int'),
'ProductName' => array('name' => 'ProductName','type' => 'xsd:string'),
'ImageUrl' => array('name' => 'ImageUrl','type' => 'xsd:string')
)
);
$server->wsdl->addComplexType(
'ProductsArray',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:Products[]')
),
'tns:Products'
);
$server->register('GetProductDetails', // method name
array('AgentId' => 'xsd:string'), // input parameters
array('return' => 'tns:ProductsArray'), // output parameters
$namespace, // namespace
$namespace . '#GetProductDetails', // soapaction
'rpc', // style
'sequence', // use
'Get Product Details' // documentation
);
function GetProductDetails($AgentId)
{
$productArray = array();
$sqlQry="SELECT pr.products_id, pr.products_image, pd.products_name FROM `products` pr left join products_description pd on pr.products_id=pd.products_id";
$result=mysql_query($sqlQry);
while($row=mysql_fetch_array($result)){
$product=array();
$product["ID"]=$row['products_id'];
$product["ProductName"]=$row['products_name'];
$product["ImageUrl"]=$row['products_image'];
$productArray[]=$product;
}
return $productArray;
}
$HTTP_RAW_POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA'])?$GLOBALS['HTTP_RAW_POST_DATA'] : '';
$server->service($HTTP_RAW_POST_DATA);
and I am getting response in android something like
[Products{ID=29; Name=product1; Url=product1.jpg; }, Products{ID=30; Name=product2; Url=product2.jpg; }]
this responce is in one element of response.getProperty(0)
and if I paste this code in http://jsonviewer.stack.hu/ site then it tells me it is not valid json, I am new in nusoap so I don't know how this gives json/XML response
Is there any problem with code?
I have also tried
Android Code:
SoapObject response = (SoapObject) envelope.bodyIn;
SoapObject nameResult = (SoapObject) response.getProperty(0);
In above nameResult I am getting all response in one single property.
I have never used nusoap before but from what I can tell your properly connecting to your db, and according to what i found nusoap can run standard php scripts in which case replaces function GetProductDetails with what i have below (I'm using json_encode), Your problem was with how you load a single result inside the while loop you must use array_push() instead.
function GetProductDetails($AgentId)
{
// array for JSON response
$productArray = array();
$sqlQry="SELECT pr.products_id, pr.products_image, pd.products_name FROM `products` pr left join products_description pd on pr.products_id=pd.products_id";
$result=mysql_query($sqlQry);
while ($row = mysql_fetch_array($result)) {
// temp user array
$product=array();
$product["ID"]=$row['products_id'];
$product["ProductName"]=$row['products_name'];
$product["ImageUrl"]=$row['products_image'];
// push single product into final response array
array_push($poductArray["products"], $product);
}
// echoing JSON response
echo json_encode($productArray);
}
Hope this works it's clearly untested as I dont have your sql (but it's copied from similar script on my server and rewritten for your purposes) also you should cover the case your database is empty
I have solved it by my self, this is help here if any one needs how to solve this..
I am getting response is parsed using Vector and after that I just simply make a loop that get every attribute and add to ArrayList<HashMap<String, String>>.
My process is like, get response from webservice and parsing that response using vector and I just retrieve properties and add to ArrayList<HashMap<String, String>>.
So If here anyone wants to parse complexType Array Response and finds problem like me, they can find solution like following code
public static final ArrayList<HashMap<String, String>> productMapArray = new ArrayList<HashMap<String, String>>();
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
request.addProperty("user_id", "1");
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
Vector<SoapObject> response = (Vector<SoapObject>)envelope.getResponse();
for (SoapObject soapObject : response) {
HashMap<String, String> map = new HashMap<String, String>();
map.put(KEY_ID, soapObject.getProperty(KEY_ID).toString());
map.put(KEY_PRODUCT, soapObject.getProperty(KEY_PRODUCT).toString());
map.put(KEY_IMG, soapObject.getProperty(KEY_IMG).toString());
productMapArray.add(map);
}
if (response.toString().equalsIgnoreCase("invalid")) {
result = false;
} else {
result = true;
}
} catch (SocketException ex) {
result = false;
Log.e("Error : ", "Error on soapPrimitiveData() " + ex.getMessage());
ex.printStackTrace();
} catch (Exception e) {
result = false;
Log.e("Error : ", "Error on soapPrimitiveData() " + e.getMessage());
e.printStackTrace();
}
return result;

Categories