0

I made a post request with the following code in Android using Volley.

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Method.POST, ServerURL.URL_REGISTER, new Response.Listener<JSONObject>() {

    @Override
    public void onResponse(JSONObject response) {
        Log.d(TAG_REGISTER, "Register Response: " + response.toString());
        pDialog.dismiss();

        try {
            JSONObject jObj = new JSONObject(response.toString());
            boolean error = jObj.getBoolean("error");
            if (!error) {
                // User successfully stored in MySQL
                // Now store the user in sqlite
                String uid = jObj.getString("uid");

                JSONObject user = jObj.getJSONObject("user");
                String name = user.getString("name");
                String email = user.getString("email");
                String created_at = user
                        .getString("created_at");

                // Inserting row in users table
                db.addUserIntoSQLite(name, email, uid, created_at);

                Toast.makeText(getActivity(), "User successfully registered. Try login now!", Toast.LENGTH_LONG).show();

                // Launch main activity
                Intent intent = new Intent(getActivity(), MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                getActivity().overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
                startActivity(intent);
                getActivity().finish();

            } else {

                // Error occurred in registration. Get the error
                // message
                String errorMsg = jObj.getString("error_msg");
                Toast.makeText(getActivity(), errorMsg, Toast.LENGTH_LONG).show();
            }
        } catch (JSONException e) {
            Toast.makeText(getActivity(), "JSONException: " + e.getMessage(), Toast.LENGTH_LONG).show();
        }

    }
}, new Response.ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError error) {
        Log.e(TAG_REGISTER, "Registration Error: " + error.getMessage());
        Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_LONG).show();
        pDialog.dismiss();
    }
}) {

    @Override
    public String getBodyContentType() {
        return "application/json; charset=utf-8";
    }

    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        HashMap<String, String> params = new HashMap<>();
        params.put("tag", "register");
        params.put("name", name);
        params.put("email", email);
        params.put("password", password);
        return params;
    }
};

Now here's the PHP part that receives the post request and get the post values.

<?php
session_start();

if (!empty($_POST['tag'])) {

    // get tag
    $tag = $_POST['tag'];

    // include db handler
    require_once 'mysql/DB_Functions.php';
    $db = new DB_Functions();

    // response Array
    $response = array("tag" => $tag, "error" => FALSE);

    // check for tag type
    if ($tag == 'login') {
        // Request type is check Login
        $email = $_POST['email'];
        $password = $_POST['password'];

        // check for user
        $user = $db->getUserByEmailAndPassword($email, $password);
        if ($user != false) {
            // user found
            $response["error"] = FALSE;
            $response["uid"] = $user["unique_id"];
            $response["user"]["name"] = $user["name"];
            $response["user"]["email"] = $user["email"];
            $response["user"]["created_at"] = $user["created_at"];
            $response["user"]["updated_at"] = $user["updated_at"];
            echo json_encode($response);
        } else {
            // user not found
            // echo json with error = 1
            $response["error"] = TRUE;
            $response["error_msg"] = "Incorrect email or password!";
            echo json_encode($response);
        }
    } else if ($tag == 'register') {
        // Request type is Register new user
        $name = $_POST['name'];
        $email = $_POST['email'];
        $password = $_POST['password'];

        // check if user is already existed
        if ($db->userExists($email)) {
            // user is already existed - error response
            $response["error"] = TRUE;
            $response["error_msg"] = "User already exists";
            echo json_encode($response);
        } else {
            // store user
            $user = $db->storeUser($name, $email, $password);
            if ($user) {
                // user stored successfully
                $response["error"] = FALSE;
                $response["uid"] = $user["unique_id"];
                $response["user"]["name"] = $user["name"];
                $response["user"]["email"] = $user["email"];
                $response["user"]["created_at"] = $user["created_at"];
                $response["user"]["updated_at"] = $user["updated_at"];
                echo json_encode($response);
            } else {
                // user failed to store
                $response["error"] = TRUE;
                $response["error_msg"] = "Error occured in Registartion";
                echo json_encode($response);
            }
        }
    } else {
        // user failed to store
        $response["error"] = TRUE;
        $response["error_msg"] = "Unknow 'tag' value. It should be either 'login' or 'register'";
        echo json_encode($response);
    }
} else {
    $response["error"] = TRUE;
    $response["error_msg"] = "Operation failed due to the missing tag!";
    echo json_encode($response);
}

var_dump($_SERVER['REQUEST_METHOD'], $_POST);
?>

I should be able to get the 'tag' value, but the problem is that it keeps saying that the 'tag' is missing.

So now I created an HTML file to test which part has a problem.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="index.php" method="post">
Tag: <input type="text" name="tag"><br>
Name: <input type="text" name="name"><br>
Email: <input type="text" name="email"><br>
Password: <input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>

As I put the data in this HTML file, the data is successfully stored in the MySQL database. Which part do you think has the problem?

I've searched all the solutions regarding the Volley part, and my Volley part doesn't seem to have the problem. So I believe it's the PHP part that's causing the issue.

If I open the PHP file on the web, it shows the following message.

{"error":true,"error_msg":"Operation failed due to the missing tag!"}string(3) "GET" array(0) { }
MarshallLee
  • 1,290
  • 4
  • 23
  • 42
  • As an aside, if you're planning to collect login info or other sensitive data, be sure to do so via https and follow security best practices. A good starting place is here: http://developer.android.com/training/best-security.html – Matthew MacGregor Nov 13 '15 at 04:47

1 Answers1

2

The problem is that you are sending data from the Volley library as content type application/json but your PHP script is expecting POST data as content type application/x-www-form-urlencoded. This is why your POST from the web form worked, but your POST from Volley did not.

In your PHP script, do this:

$data = json_decode(file_get_contents('php://input'), true);

if (empty($data['tag']) == false) {
    $tag = $data['tag'];
    echo $tag;
}

Because you're sending the data as JSON, PHP won't automatically parse it into the $_POST global. What the code above does is get the raw POST data as a string and parse it into an array.

Update

I spent some more time debugging this and now have a full solution:

PHP:

Change your script to access the raw POST data using the method I listed above, instead of $_POST global. Use this code for debugging purposes:

<?php

$data = json_decode(file_get_contents('php://input'), true);

if (empty($data['tag']) == false) {
    $tag = $data['tag'];
}

echo json_encode([ "tag" => $tag ]);
?>

Android:

getParams() is apparently not used with JsonObjectRequest class, so your body is empty. See the answer to this question for details of that. Instead, you must pass your body as a JsonObject in the constructor to JsonObjectRequest. For example:

    HashMap<String, String> params = new HashMap<>();
    params.put("tag", "register");
    params.put("name", "myname");
    params.put("email", "myname@email.com");
    params.put("password", "meow");
    JSONObject o = new JSONObject(params);
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
        Request.Method.POST, 
        ServerURL.URL_REGISTER, 
        o, 
        new Response.Listener<JSONObject>() { // ... 

Result:

D/EXAMPLE: Register Response: {"tag":"register"}

I've created a more complete example as a gist.

Note: If you are making requests to a development server on your local machine, you'll need to use 10.0.2.2:PORT instead of localhost:PORT. I'm assuming that this is not an issue in your case, since you seem able to connect to your server, but include this note for completeness for any future readers.

Community
  • 1
  • 1