Thursday 30 March 2023

Volley throws AuthFailureError

I am using Volley to upload pictures from Android application to server. In case when I have more than 3 pictures for upload, Volley throws AuthFailureError, even though I don't use any kind of authentication. For each picture, I am using separate request, which is sent when I receive response for previous one. Here is a code. Does anyone know what is the problem? Or shall I simply switch to Retrofit? Thanks!

private void sendRequest(String control){

    Toast.makeText(MainReviewActivity.this, control, Toast.LENGTH_LONG).show();

    //Toast.makeText(AfterLoginActivity.this, control, Toast.LENGTH_LONG).show();

    StringRequest stringRequest = new StringRequest(Request.Method.POST, UploadUrl, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            try {
                waiting_search_results = 0;
                JSONObject jsonObject = new JSONObject(response);
                String Response = jsonObject.getString("response");
                if (control.equals("review_page_restaurant_search") || control.equals("review_page_meal_search")){
                    prepareSearchResultDataFromServer(control, Response);
                } else{
                    if (control.equals("review_page_perform_review")){
                        if (Response.equals("Success")){
                            // check if there are pics to send
                            Log.d("debug:", "Perform review - positive resp received");
                            enablePicSending = 1;
                        } else{
                            loadingDialog.dismissDialog();
                            Toast.makeText(MainReviewActivity.this, "Greška u slanju ocene, pokušajte ponovo", Toast.LENGTH_LONG).show();
                        }
                    } else{
                        // control equals "review_page_upload_pic"
                        Log.d("debug:", "Uploading pic - resp received");
                        waitingPicSendingResp = 0;
                    }
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(final VolleyError error) {
            loadingDialog.dismissDialog();
            Log.d("debug:", "Error occurred: " + error);
            //Bundle bundle = new Bundle();
            //bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "string");
            //bundle.putString(FirebaseAnalytics.Param.CONTENT, "Volley failed during: " + control + ", reason: " + error);
            //mFirebaseAnalytics.logEvent("Sending_failed", bundle);
            Toast.makeText(MainReviewActivity.this, error.toString(), Toast.LENGTH_LONG).show();
            if (control.equals("review_page_upload_pic")){
                Toast.makeText(MainReviewActivity.this, "Slanje slika nije uspelo, pokušajte ponovo", Toast.LENGTH_LONG).show();
            } else{
                if (control.equals("review_page_perform_review")){
                    Toast.makeText(MainReviewActivity.this, "Slanje ocene nije uspelo, pokušajte ponovo", Toast.LENGTH_LONG).show();
                } else{
                    Toast.makeText(MainReviewActivity.this, "Greška u komunikaciji", Toast.LENGTH_LONG).show();
                }
            }
            finish();
        }
    })

    {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {

            Map<String, String> params = new HashMap<>();

            params.put("control", control);
            params.put("city", selectedCity);
            if (control.equals("review_page_restaurant_search")){
                params.put("search_word", search_word);
            } else{
                if (control.equals("review_page_meal_search")){
                    params.put("search_word", search_word);
                    params.put("restaurant", selectedRestaurant);
                } else{
                    if (control.equals("review_page_perform_review")){
                        params.put("reviewer_pic", reviewer_pic);
                        params.put("reviewer_name", person_name);
                        params.put("reviewer_nick", reviewer_nick);
                        params.put("review_date", date);
                        params.put("restaurant", selectedRestaurant);
                        params.put("ambient", ambientGrade);
                        params.put("quick", quickGrade);
                        params.put("ratio", ratioGrade);
                        params.put("personnel", personnelGrade);
                        params.put("restaurant_comment", restaurantComment);
                        params.put("meal", selectedMeal);
                        params.put("amount", amountGrade);
                        params.put("taste", tasteGrade);
                        params.put("price", priceGrade);
                        params.put("meal_comment", mealComment);
                    } else{
                        if (control.equals("review_page_upload_pic")){
                            Log.d("debug:", "Triggering pic sending: " + picType);
                            Log.d("debug:", "Restaurant: " + selectedRestaurant);
                            Log.d("debug:", "Meal: " + selectedMeal);
                            //Bundle bundle = new Bundle();
                            //bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "string");
                            //bundle.putString(FirebaseAnalytics.Param.CONTENT, "Triggering pic sending: " + picType + ", restaurant: " + selectedRestaurant + ", meal: " + selectedMeal);
                            //mFirebaseAnalytics.logEvent("Pic_sending", bundle);
                            params.put("type", picType);
                            params.put("pic", pic);
                            params.put("restaurant", selectedRestaurant);
                            params.put("meal", selectedMeal);
                        } else{
                            // should not happen
                        }
                    }
                }
            }

            return params;
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<>();
            headers.put("User-Agent", "Mozilla/5.0");

            return headers;
        }

        @Override
        public String getBodyContentType() {
            return "application/x-www-form-urlencoded";
        }
    };

    RequestQueue requestQueue = Volley.newRequestQueue(MainReviewActivity.this);
    requestQueue.add(stringRequest);
}

EDIT I read more about Authentication failure and I noticed in documentation that when that happens, server shall provide WWW-Authenticate response header, so I tried to read it with parseNetworkResponse function. In the moment of Toasting (i.e. the moment after parsing the latest network response), my observations are following: WWW-Authenticate header is missing, some pictures are not uploaded to server, server provided response 200, but Volley called onErrorResponse method (from which I am Toasting). How is it possible to receive response 200, but AuthFailureError is detected in OnErrorResponse method? New code, with parsing network response and debug Toasts:

private void sendRequest(String control){

    //Toast.makeText(MainReviewActivity.this, control, Toast.LENGTH_LONG).show();

    //Toast.makeText(AfterLoginActivity.this, control, Toast.LENGTH_LONG).show();

    StringRequest stringRequest = new StringRequest(Request.Method.POST, UploadUrl, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            try {
                waiting_search_results = 0;
                JSONObject jsonObject = new JSONObject(response);
                String Response = jsonObject.getString("response");
                if (control.equals("review_page_restaurant_search") || control.equals("review_page_meal_search")){
                    prepareSearchResultDataFromServer(control, Response);
                } else{
                    if (control.equals("review_page_perform_review")){
                        if (Response.equals("Success")){
                            // check if there are pics to send
                            Log.d("debug:", "Perform review - positive resp received");
                            enablePicSending = 1;
                        } else{
                            loadingDialog.dismissDialog();
                            Toast.makeText(MainReviewActivity.this, "Greška u slanju ocene, pokušajte ponovo", Toast.LENGTH_LONG).show();
                        }
                    } else{
                        // control equals "review_page_upload_pic"
                        success_count++;
                        //Toast.makeText(MainReviewActivity.this, Response, Toast.LENGTH_LONG).show();
                        Log.d("debug:", "Uploading pic - resp received");
                        waitingPicSendingResp = 0;
                    }
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(final VolleyError error) {
            loadingDialog.dismissDialog();
            Log.d("debug:", "Error occurred: " + error);
            error_count++;
            Toast.makeText(MainReviewActivity.this, "Parse count: " + String.valueOf(parse_count), Toast.LENGTH_LONG).show();
            Toast.makeText(MainReviewActivity.this, "Error count: " + String.valueOf(error_count), Toast.LENGTH_LONG).show();
            Toast.makeText(MainReviewActivity.this, "Success count: " + String.valueOf(success_count), Toast.LENGTH_LONG).show();
            for (int i = 0; i < names.length; i++){
                Toast.makeText(MainReviewActivity.this, "Name: " + names[i] + " Value: " + values[i], Toast.LENGTH_LONG).show();
            }
            //Toast.makeText(MainReviewActivity.this, "Success: " + String.valueOf(success_count) + " Error: " + String.valueOf(error_count) + "Parse: " + String.valueOf(parse_count), Toast.LENGTH_LONG).show();
            //Toast.makeText(MainReviewActivity.this, error.getCause().toString(), Toast.LENGTH_LONG).show();
            //Toast.makeText(MainReviewActivity.this, error.getCause().getMessage(), Toast.LENGTH_LONG).show();
            //Toast.makeText(MainReviewActivity.this, error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
            //Bundle bundle = new Bundle();
            //bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "string");
            //bundle.putString(FirebaseAnalytics.Param.CONTENT, "Volley failed during: " + control + ", reason: " + error);
            //mFirebaseAnalytics.logEvent("Sending_failed", bundle);
            //Toast.makeText(MainReviewActivity.this, error.toString(), Toast.LENGTH_LONG).show();
            if (control.equals("review_page_upload_pic")){
                Toast.makeText(MainReviewActivity.this, "Slanje pojedinih slika nije uspelo, ali je ocena poslata uspešno", Toast.LENGTH_LONG).show();
            } else{
                if (control.equals("review_page_perform_review")){
                    Toast.makeText(MainReviewActivity.this, "Slanje ocene nije uspelo, pokušajte ponovo", Toast.LENGTH_LONG).show();
                } else{
                    Toast.makeText(MainReviewActivity.this, "Greška u komunikaciji", Toast.LENGTH_LONG).show();
                }
            }
            finish();
        }
    })

    {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {

            Map<String, String> params = new HashMap<>();

            params.put("control", control);
            params.put("city", selectedCity);
            if (control.equals("review_page_restaurant_search")){
                params.put("search_word", search_word);
            } else{
                if (control.equals("review_page_meal_search")){
                    params.put("search_word", search_word);
                    params.put("restaurant", selectedRestaurant);
                } else{
                    if (control.equals("review_page_perform_review")){
                        params.put("reviewer_pic", reviewer_pic);
                        params.put("reviewer_name", person_name);
                        params.put("reviewer_nick", reviewer_nick);
                        params.put("review_date", date);
                        params.put("restaurant", selectedRestaurant);
                        params.put("ambient", ambientGrade);
                        params.put("quick", quickGrade);
                        params.put("ratio", ratioGrade);
                        params.put("personnel", personnelGrade);
                        params.put("restaurant_comment", restaurantComment);
                        params.put("meal", selectedMeal);
                        params.put("amount", amountGrade);
                        params.put("taste", tasteGrade);
                        params.put("price", priceGrade);
                        params.put("meal_comment", mealComment);
                    } else{
                        if (control.equals("review_page_upload_pic")){
                            Log.d("debug:", "Triggering pic sending: " + picType);
                            Log.d("debug:", "Restaurant: " + selectedRestaurant);
                            Log.d("debug:", "Meal: " + selectedMeal);
                            //Bundle bundle = new Bundle();
                            //bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "string");
                            //bundle.putString(FirebaseAnalytics.Param.CONTENT, "Triggering pic sending: " + picType + ", restaurant: " + selectedRestaurant + ", meal: " + selectedMeal);
                            //mFirebaseAnalytics.logEvent("Pic_sending", bundle);
                            params.put("type", picType);
                            params.put("pic", pic);
                            params.put("restaurant", selectedRestaurant);
                            params.put("meal", selectedMeal);
                        } else{
                            // should not happen
                        }
                    }
                }
            }

            return params;
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<>();
            headers.put("User-Agent", "Mozilla/5.0");
            headers.put("Content-Type", "application/x-www-form-urlencoded");

            return headers;
        }

        @Override
        public String getBodyContentType()
        {
            return "application/x-www-form-urlencoded";
        }

        @Override
        protected Response<String> parseNetworkResponse(NetworkResponse response) {

            parse_count++;

            names = new String[response.allHeaders.size()];
            values = new String[response.allHeaders.size()];

            for (int i = 0; i < response.allHeaders.size(); i++){
                names[i] = response.allHeaders.get(i).getName();
                values[i] = response.allHeaders.get(i).getValue();
                Log.d("debug:", "parse_count" + parse_count);
                Log.d("debug:", "names" + i + ": " + names[i]);
                Log.d("debug:", "values" + i + ": " + values[i]);
            }

            return super.parseNetworkResponse(response);
        }
    };

    RequestQueue requestQueue = Volley.newRequestQueue(MainReviewActivity.this);
    requestQueue.add(stringRequest);
}


from Volley throws AuthFailureError

No comments:

Post a Comment