6

I am using the following code to store the ParseObject with a ParseFile. I have enabled Parse local datastore in Application subclass. This code storing an instance of the ParseObject in local datastore and in the parse server when the application in connected to the internet.

final ParseFile file = new ParseFile(position + ".mp4", data);
    file.saveInBackground(new SaveCallback() {

        @Override
        public void done(ParseException e) {
            ParseObject po = new ParseObject("Recordings");
            po.put("code", position);
            po.put("name", myname);
            po.put("file", file);
            po.saveEventually();                
        }
    });

Same code when the app is not connected to internet is throwing the following Exception. java.lang.IllegalStateException: Unable to encode an unsaved ParseFile. And the app is crashing. Object is not stored in local datastore.

So how can I store a ParseObject with a ParseFile in parse local datastore when there is no internet?

mithrop
  • 3,283
  • 2
  • 21
  • 40
ashokgujju
  • 320
  • 2
  • 4
  • 17
  • Correct me if I'm wrong, but you are saving directly to parse server. You should use pinInBackground instead and try to save to parse only if you have an internet connection. – clauziere Aug 26 '15 at 22:58

3 Answers3

7

I have solved this problem by simply storing the bytes of the file with ParseObject. When I want my file, I am writing those bytes back to a file.

My requirement was to store a audio recording file with name in the parse. I followed the these steps: 1. Get the byte array of file 2. Put the byte array into ParseObject 3. Call ParseObject#saveEventually()

Code:

    File file = new File(filePath);
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(file);
        byte data[] = new byte[(int) file.length()];
        fis.read(data);

        ParseObject obj = new ParseObject("Recordings");
        obj.put("name", name);          
        obj.put("data", data);
        obj.saveEventually();
    } catch (IOException e) {
        e.printStackTrace();
    }
ashokgujju
  • 320
  • 2
  • 4
  • 17
1

I really liked ashokgujju's solution. In my case, I wanted to save a picture from an Android device in offline mode, so this is what happened to me:

1.- Only by doing that (ashokgujju's solution) will not add a file into your parse table, as SAndroidD pointed out, if you want that, you might use an aftersave Parse Cloud function, something like this:

Parse.Cloud.afterSave("Recordings_or_WhatEverYourTableIs", function(request){
    bytes = request.object.get("data"); //"data" is the name given by  ashokgujju at "obj.put("data", data);"

    if(bytes){
         var file = new Parse.File("myFile.png", bytes); //png or whatever you want
         file.save().then(function(success){
                  request.object.set("record_or_MyColumnWithParseFile", file);
                  request.object.unset("data"); //optional, if you are not going to use this data, it has no meaning keep it there anymore and you will save some space
                  request.object.save();
         },function(error){
                  //error
         }); 
    }

}

That worked like a charm! but...

2.- But only for the Thumbnail, I mean, a very small picture, once I wanted to do the same with a big picture, I faced this:

com.parse.ParseRequest$ParseRequestException: The object is too large -- should be less than 128 kB

It took me a while to realise that, because no errors where shown, just like SAndroidD was saying. I had to add a callback to saveEventually to see it.

  File file = new File(filePath);
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(file);
        byte data[] = new byte[(int) file.length()];
        fis.read(data);

        ParseObject obj = new ParseObject("Recordings");
        obj.put("name", name);          
        obj.put("data", data);
        obj.saveEventually(new SaveCallback() {
                    @Override
                    public void done(ParseException e) {
                        Log.i(MyClass.logName," is it everything ok boy? "+e);
                    }
                });
    } catch (IOException e) {
        e.printStackTrace();
    }

So! to summarize: ashokgujju's cool workaround plus my afterSave function will save any parseFile in offline mode, as long as the file itself is not that big.

DanixDani
  • 186
  • 1
  • 6
0

I found a solution of this problem

ckeckout this code

File file = new File(imagePath);
                FileInputStream fis = null;
                try {
                    fis = new FileInputStream(file);
                    byte data[] = new byte[(int) file.length()];
                    fis.read(data);

                    final ParseFile f=new ParseFile("img", data);

                    f.saveInBackground(new SaveCallback() {

                        @Override
                        public void done(ParseException arg0) {
                            //if (arg0.equals(null)) {
                                 ParseObject oImg=new ParseObject("Image");
                                 oImg.put("img", f);
                                 oImg.put("name", edtUN.getText().toString());

                                 oImg.saveEventually(new SaveCallback() {

                                    @Override
                                    public void done(ParseException arg1) {

                                        System.out
                                        .println("img save...");

                                    }
                                });
                            //}
                        }
                    }, new ProgressCallback() {

                        @Override
                        public void done(Integer arg0) {
                            //display img upload progress

                        }
                    });

and then when net is on and where open then write in onResume() method of your first activity

ParseQuery<ParseObject> queryImg = ParseQuery.getQuery("Image");
            queryImg.fromPin(ApplicationParse.TODO_GROUP_NAME);
            queryImg.whereEqualTo("isDraft", true);
            queryImg.findInBackground(new FindCallback<ParseObject>() {

                @Override
                public void done(List<ParseObject> todos, ParseException e) {
                    if (e == null) {
                        for (final ParseObject todo : todos) {
                            // Set is draft flag to false before syncing to Parse
                            // todo.setDraft(false);
                            todo.saveInBackground(new SaveCallback() {

                                @Override
                                public void done(ParseException e) {
                                    //if (e == null) {
                                        // Let adapter know to update view
                                        if (!isFinishing()) {
                                            //refresh list data

                                            System.out.println("Image DATA is saved ..... ");

                                        }

                                }

                            });

                        }
                    } else {
                        Log.i("MainActivity","syncTodosToParse: Error finding pinned todos: "+ e.getMessage() );
                        e.printStackTrace();
                    }
                }

            });
SAndroidD
  • 1,745
  • 20
  • 33
  • 3
    bro.. my problem was all about storing ParseFile in OFFLINE mode. In your first code snippet, you are trying store ParseFile using ParseFile#saveInBackground(). How do you expect this works in OFFLINE mode? sorry to say that your answer is completely irrelevant. – ashokgujju Dec 24 '14 at 10:52
  • It work for some time but not all time :( .and if I m trying ur solution then it give parse file error "File type not match" What should I do?? Please help me solve this issue.. :( – SAndroidD Dec 24 '14 at 12:28
  • check this link I m trying this http://www.acnenomor.com/397113p1/android-save-files-in-offline-mode-parsecom – SAndroidD Dec 24 '14 at 12:30
  • 1
    I wrote an article. Please check this link http://www.cumulations.com/blogs/8/Problem-with-ParseFile-in-offline-mode – ashokgujju Dec 24 '14 at 12:39
  • I m trying this link also but it can not save Image on parse – SAndroidD Dec 24 '14 at 12:49
  • 1
    dude read that article again.. forget about ParseFile.. just put the image byte array in ParseObject and call ParseObject#saveEventually()... – ashokgujju Dec 24 '14 at 12:56
  • Yes I am doing same .I m putting byte[] on file value and then saveEventually() this parse object .but it not put file on parse.com when net is on – SAndroidD Dec 24 '14 at 13:22
  • @ashokgujju : The solution you mentioned worked only for small fie right? If I have files of size of more than 1 MB, does this solution work? – Swapnil Dec 09 '16 at 06:14
  • @swapnil I have used above solution to store 4mb files it worked pretty well for me. Give it a try! – ashokgujju Dec 10 '16 at 15:03