Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pin a ParseObject with a ParseFile to the Parse Local Datastore in OFFLINE?

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?

like image 373
ashokgujju Avatar asked Oct 31 '14 09:10

ashokgujju


2 Answers

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();
    }
like image 180
ashokgujju Avatar answered Oct 16 '22 04:10

ashokgujju


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.

like image 30
DanixDani Avatar answered Oct 16 '22 02:10

DanixDani