5

Hi I'm using the Google Drive Api to store a database using the AppDataFolder facility. I have a test app running successfully on one device. I am able to upload/update/delete/download the database file and reintegrate it into the program with no problems.

The issue I'm having is when I want to share this database with another device running the same app, then things don't work as expected. Example device A I upload the database, device B - I want to download the database but no file is found (this delay can vary greatly from seconds to hours). Reason for this - when using the Api it decides when it wants to 'sync' data, as it is queued rather than being instantaneously uploaded. So when used on one device this is not a problem because it takes either the 'synced' file from the cloud storage, or file waiting to be synced.

I have tried various things like trying to list all AppDataFolder files or retrieving metadata through a query with searchable filters before making a request to update/delete etc.. However I can't get it to work as desired fundamentally it chooses when to sync.

So my actual question is: How can I force Google Drive to sync my file when I want it to i.e. every time a request is made, so that synchronisation is achieved across multiple devices using the same app. There must be an answer as I would think this is quite a fundamental reason why you would use the AppDataFolder is the first place.

Thanks in advance

EDIT/UPDATE:

I have been able to find an option in the Api to 'sync' the drive content using this code:

            // try to sync
            Drive.DriveApi.requestSync(mGoogleApiClient).setResultCallback(new ResultCallback<com.google.android.gms.common.api.Status>() {
                @Override
                public void onResult(com.google.android.gms.common.api.Status status) {
                    if (!status.getStatus().isSuccess()) {
                        Log.e("SYNCING", "ERROR" + status.getStatusMessage());
                    } else {
                        Log.e("SYNCING", "SUCCESS");
                        // execute async task to list AppFolderContents
                        new AppFolderContentsAsyncTask(getActivity()).execute();
                    }
                }
            });

This works well for 3/4 attempts in quick succession, however I reach a syncing limit and status message:

ERRORSync request rate limit exceeded.

Is there any way to increase the request rate as this is not really desirable if I have to have a app that prompts the user 'please try again later to sync - not sure how long you'll have to wait until you can though!'

SOLUTION - OF SORTS, AND MY THOUGHTS (for what its worth)

The solution that I am going for (after emailing a app dev whose published a drive app that synchronizes without problems) is to use the Drive REST Api, rather than the newer (and Google preferred) Drive API. I tried limiting the 'requestSync' to only when the user navigated to a fragment with the Drive options (rather than every file transaction). However this would probably solve the requestSync rate limit for the most part, but it still could hit that limit. Also if multiple devices are running the app, and linked to the same Drive account were both syncing/uploading/deleting files at the same time in the app then there is a possibility of losing synchronization - maybe a rare scenario, but still possible. I don't feel that making a user wait to sync files is a viable option in terms of user experience or app design.

Curious though - The actual Drive app lets you refresh (requestSync?) as many times as you like. I created 20 folders on the web interface in quick succession, after each folder was created I refreshed the Drive app on my phone and it synced all 20 times. It seems Google understands the importance of synchronization, but chooses to make this quite difficult ensure this in their new Drive API. As already stated uploading files to the cloud storage happens usually instantly (it is queued, however if you have connectivity it happens almost straight away). I would have thought that this is the costly transaction in terms of moving data/updating drive contents, rather than just querying for synchronization of files. However you can keep adding files to your your drive app one at a time, and it uploads them one at a time almost instantly - where as you request sync more than 4 times in 30 seconds and it then fails and you have to 'cool off' for a while.

I'm very new to programming/Android in general - as soon as I learn something new, I realize how little I actually know, so if their is a better solution out there using the Drive API (rather than REST API) I'd very much welcome it.

Mark
  • 9,604
  • 5
  • 36
  • 64
  • 1
    Hi, in fact we came across a different situation. The old REST API is requiring runtime GET_ACCOUNTS permission in Android 6 - http://stackoverflow.com/q/34639890/72437 We are moving away from REST API to google-drive-android-api. But, currently facing the same problem as you do... – Cheok Yan Cheng Jan 12 '16 at 18:57
  • @Cheok Yan Cheng The project I was using this with I have shelved for now, simply because I'm trying to learn and gain more general experience, rather than get bogged down with the subtleties of the API. I can't think of a easy resolution where multi device synchronisation can occur in quick succession with out hitting the 'sync limit'. Having a 'Sync Button' in my app become inactive for 30 seconds once pressed preventing further syncing to avoid the limit doesn't sit right with me, or 'pending' syncs waiting to avoid the limit. Funny how Drive App syncs as many times as you like! – Mark Jan 12 '16 at 19:33
  • May I know how quickly you hit the requestSync? Do you still remember, how many times of request you are making per minute, to hit the quota? – Cheok Yan Cheng Jan 13 '16 at 02:05
  • From memory I called requestSync 3, maybe 4 times (once every 7-8 seconds) then I'd hit the limit (in a use case scenario this could easily happen), and have to wait couple or so minutes before requestSync was successful again. You could implement a exponential cool off wait time - which would obviously work, but this would cause a synchronisation delay across multiple devices running the app with the same account login. Their is, to my mind no way around it, as its hardcoded into the Drive API. I couldn't find any documentation on sync quotas, frequency of sync requests or cool off periods – Mark Jan 13 '16 at 02:41

1 Answers1

7

DriveApi#requestSync will let you request a "sync down" from the server to the device. This way, on the second device you should be able to see the content uploaded from the first device. However, the calls to request sync are rate limited (per-device) to avoid abuse and guarantee a reasonable amount of data usage by the Drive API. You should ideally call request sync only when you need to. There's no way to increase the rate limit.

Regarding upload completion, after committing an upload, you shouldn't use request sync since that won't help you (it only syncs down but not up). The actual upload will happen as soon as possible (based on the device's connectivity and the preferences specified by your app through DrivePreferencesApi, which by default are unrestricted).

If you want to know when the actual upload happened, you can use CompletionEvents. This way you can test your app with more insights on what's actually going on.

Luis
  • 131
  • 3
  • Thank you, very helpful information - I have figured out several routes I can take to overcome this issue and I am looking into the points you have mentioned above. – Mark Jul 06 '15 at 08:48
  • @MarkKeen Would you mind sharing which are those routes and what did you do at the end? – sorianiv Jul 24 '15 at 00:00
  • @sorianiv - see edit in original question - a solution of sorts. – Mark Jul 24 '15 at 09:33