Exception when getting data back from Parse Server's ParseFile

孤街醉人 提交于 2020-01-25 07:29:06

问题


I'm storing some images on Parse Server for my Instagram Clone app. When trying to retrieve them using:

ParseFile file = imageToDisplay.getParseFile("image");
byte[] data = file.getData();

everything works just fine as long as there are still some images in cache but if I reinstall the app or try to get data of other users images I get an exception:

2019-12-12 14:24:44.005 15502-15502/com.example.instagramclone E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.instagramclone, PID: 15502
    java.lang.IllegalArgumentException: Expected URL scheme 'http' or 'https' but no colon was found
        at okhttp3.HttpUrl$Builder.parse(HttpUrl.java:1333)
        at okhttp3.HttpUrl.get(HttpUrl.java:916)
        at okhttp3.Request$Builder.url(Request.java:165)
        at com.parse.ParseHttpClient.getRequest(ParseHttpClient.java:132)
        at com.parse.ParseHttpClient.executeInternal(ParseHttpClient.java:68)
        at com.parse.ParseHttpClient.execute(ParseHttpClient.java:57)
        at com.parse.ParseRequest$3.then(ParseRequest.java:133)
        at com.parse.ParseRequest$3.then(ParseRequest.java:130)
        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:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)

Same thing happens when I use:

file.getDataInBackground(new GetDataCallback() {
    @Override
    public void done(byte[] data, ParseException e) {
        // More code
    }
});

Exception is in the parameter this time. To note saving and retrieving of anything else, so far worked perfectly.

It seems like urls to my ParseFiles are invalid. I checked that for one image with file.getUrl() and got:

undefined/files/78fc29aeab99c3e9ca6b9739efc4245658b7fd0f/087b5781e3ad8f4c3d7f85f039f6f977_image.png

Path without domain. How can I fix that?

Gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.example.instagramclone"
        minSdkVersion 23
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    implementation "com.github.parse-community.Parse-SDK-Android:parse:1.22.1"
}

Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.instagramclone">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:name=".ServerStarter"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:usesCleartextTraffic="true">
        <activity android:name=".UserFeedActivity"></activity>
        <activity
            android:name=".UserDashboardActivity"
            android:label="@string/user_dashboard_activity_label" />

        <meta-data
            android:name="com.parse.SERVER_URL"
            android:value="@string/parse_server_url" />
        <meta-data
            android:name="com.parse.APPLICATION_ID"
            android:value="@string/parse_app_id" />
        <meta-data
            android:name="com.parse.CLIENT_KEY"
            android:value="@string/parse_client_key" />

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

I save images to server using:

class SaveImageTask extends AsyncTask<Intent, Void, Void> {
    @Override
    protected Void doInBackground(Intent... intents) {
        Uri selectedImage = intents[0].getData();

        try {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImage);

            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] byteArray = stream.toByteArray();
            ParseFile file = new ParseFile("image.png", byteArray);

            ImageParseObject image = new ImageParseObject();
            image.put("image", file);
            image.put("username", ParseUser.getCurrentUser().getUsername());

            image.saveInBackground(new SaveCallback() {
                @Override
                public void done(ParseException e) {
                    if (e == null)
                        Toast.makeText(getApplicationContext(), "Image saved successfully!", Toast.LENGTH_LONG).show();
                    else {
                        Toast.makeText(getApplicationContext(), "Image saving failed!", Toast.LENGTH_LONG).show();
                        e.printStackTrace();
                    }
                }
            });
        } catch (IOException e) {
            Toast.makeText(getApplicationContext(), "Image saving failed!", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }

        return null;
    }
}

Code fragment when the exception is thrown:

Builder parse(@Nullable HttpUrl base, String input) {
    int pos = skipLeadingAsciiWhitespace(input, 0, input.length());
    int limit = skipTrailingAsciiWhitespace(input, pos, input.length());

    // Scheme.
    int schemeDelimiterOffset = schemeDelimiterOffset(input, pos, limit);
    if (schemeDelimiterOffset != -1) {
        if (input.regionMatches(true, pos, "https:", 0, 6)) {
            this.scheme = "https";
            pos += "https:".length();
        } else if (input.regionMatches(true, pos, "http:", 0, 5)) {
            this.scheme = "http";
            pos += "http:".length();
        } else {
            throw new IllegalArgumentException("Expected URL scheme 'http' or 'https' but was '"
                    + input.substring(0, schemeDelimiterOffset) + "'");
        }
    } else if (base != null) {
        this.scheme = base.scheme;
    } else {
        throw new IllegalArgumentException(
                "Expected URL scheme 'http' or 'https' but no colon was found");
    }
    ...
    ...
    ...

Configuartion class

package com.example.instagramclone;

import android.app.Application;

import com.parse.Parse;
import com.parse.ParseACL;
import com.parse.ParseObject;


public class ServerStarter extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // Enable Local Datastore.
        Parse.enableLocalDatastore(this);

        ParseObject.registerSubclass(ImageParseObject.class);

        // Add your initialization code here
        Parse.initialize(new Parse.Configuration.Builder(getApplicationContext())
                .applicationId("MY_ACTUAL_APP_ID")
                .clientKey("MY_ACTUAL_CLIENT_ID")
                .server("http://MY_ACTUAL_DOMAIN/parse/")
                .build()
        );

//        ParseUser.enableAutomaticUser();
        ParseACL defaultACL = new ParseACL();
        defaultACL.setPublicReadAccess(true);
        defaultACL.setPublicWriteAccess(true);
        ParseACL.setDefaultACL(defaultACL, true);
    }
}

Parse Server Configuartion

var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var app = express();
// Specify the connection string for your mongodb database
// and the location to your Parse cloud code
var api = new ParseServer({
    databaseURI: "mongodb://root:6fDLIHOCRnkC@127.0.0.1:27017/bitnami_parse",
    cloud: "./node_modules/parse-server/lib/cloud-code/Parse.Cloud.js",
    appId: "78fc29aeab99c3e9ca6b9739efc4245658b7fd0f",
    masterKey: "myActualMasterKey",
    serverURL: "http://myActualIP:80/parse",
    publicServerURL: "http://myActualIP:80/parse"
});
// Serve the Parse API on the /parse URL prefix
app.use('/parse', api);

var port = 1337;
app.listen(port, function() {
    console.log('parse-server running on port ' + port);
});

//Parse Dashboard
var ParseDashboard = require('parse-dashboard');
var dashboard = new ParseDashboard({
    apps: [
        {
            appName: "My Bitnami Parse API",
            appId: "78fc29aeab99c3e9ca6b9739efc4245658b7fd0f",
            masterKey: "myActualMasterKey",
            production: true,
            serverURL: "http://myActualIP:80/parse",
            publicServerURL: "http://myActualIP:80/parse"
        }
    ],
    users: [
        {
            user: "user",
            pass: "myActualPassword"
        }
    ], useEncryptedPasswords: true
});

var allowInsecureHTTP = true;

// Serve the Parse Dashboard on the /parsedashboard URL prefix
app.use('/', dashboard);

var portdash = 4040;
app.listen(portdash, function() {
    console.log('parse-dashboard running on port ' + portdash);
});

来源:https://stackoverflow.com/questions/59306303/exception-when-getting-data-back-from-parse-servers-parsefile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!