Search code examples
androidnginxparse-platformparse-serverparse-android-sdk

Parse Android fails to download image with a moved permanently error


I am getting the following exception when trying to download a ParseFile using getData() method.

com.parse.ParseException: Download from S3 failed. Moved Permanently
  at com.parse.ParseAWSRequest.onResponseAsync(ParseAWSRequest.java:43)
  at com.parse.ParseRequest$3.then(ParseRequest.java:137)
  at com.parse.ParseRequest$3.then(ParseRequest.java:133)
  at bolts.Task$15.run(Task.java:917)
  at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
  at bolts.Task.completeAfterTask(Task.java:908)
  at bolts.Task.continueWithTask(Task.java:715)
  at bolts.Task.continueWithTask(Task.java:726)
  at bolts.Task$13.then(Task.java:818)
  at bolts.Task$13.then(Task.java:806)
  at bolts.Task$15.run(Task.java:917)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
  at java.lang.Thread.run(Thread.java:818)

The ParseFile is a jpg which is uploaded and then put into a ParseObject called ImageObject. The ImageObject has several other parameters like caption, width, height which upload and download correctly. The image itself uploads correctly as confirmed through the dashboard. Only during the download I get the above exception.

This is my upload code

file.saveInBackground(new SaveCallback() {
    @Override
    public void done(ParseException e) {
        if (e == null) {
            Log.d(tag, "Successfully uploaded image file");

            ParseObject image = new ParseObject("imageObject");  //Create new Image-ParseObject and set values
            image.put("author", ParseUser.getCurrentUser());
            image.put("imageFile", file);
            image.put("caption", caption);

            image.saveInBackground(new SaveCallback() {
                @Override
                public void done(ParseException e) {
                    if(e==null){
                        Log.d(tag, "Successfully saved image file to object");
                    }else{
                        Log.d(tag, "Failed to save image file to object", e);
                    }
                }
            });
        } else {
            Log.d(tag, "Failed to save image", e);
        }
    }

my download code is pretty much ParseFile.getFile() after I have retrieved all the ImageObjects through a ParseQuery.

I Followed Line 43 of ParseAWSRequest.java and I found this,

if (statusCode >= 200 && statusCode < 300 || statusCode == 304) {
    // OK
} else {
    String action = method == ParseHttpRequest.Method.GET ? "Download from" : "Upload to";
    return Task.forError(new ParseException(ParseException.CONNECTION_FAILED, String.format(
        "%s S3 failed. %s", action, response.getReasonPhrase())));
}

This and the "Permanently removed" points to my nginx reverse proxy, which returns a 301 code in the redirect to https. Unfortunately I am not sure where to proceed from here.

Extra information, I have blocked port 80(http) in the firewall for a test and it seems that for the download parse-android-sdk is trying to download from http. Which is odd because I have specified my parse-server link with "https", and the fact that upload is working fine. I can see the uploaded image using dashboard on my server.

Using,

  • Parse Server 2.2.13
  • Parse Android SDK 1.13.1
  • Parse Dashboard 1.0.14

Solution

  • I found a workaround to this issue just by directly downloading the file. I used ParseFile.getUrl() method to get the url and then use that to download and use the file.

    In my case it was .jpg files. And then I used an external library that takes care of all the downloading/caching/loading into imageviews.

    Both of these libraries work well

    https://github.com/koush/ion

    http://square.github.io/picasso/