Android Question DropBox 2018: what is actual files sync way ?

peacemaker

Expert
Licensed User
HI, All

I see that many changes were in working with DropBox recent years...
Please, suggest for current 2018, May:
1) What is the actual lib\class\code samples to download files from end-user's account in the app ?
2) What is correct algorithm (DropBox commands steps) for files syncronization, if the periodical file list checking is required and downloading only if any change in each file was made (or new files are found) ?
 

peacemaker

Expert
Licensed User
Thanks, Don.
2) But in whole - how to check files before re-downloading?
* Listfolder
* Compare each file's date and size with the saved ones
* Save date\sizes info of all files
* Re-download file if changed or new
?

Or DropBox has more smart functions to detect changes ?
 

DonManfred

Expert
Licensed User
Or DropBox has more smart functions to detect changes ?
Yes. But it requires a Server-Part and a Webhook.
On the Server-Part you need to react on those Webhooks.

For example:
26.05.2018 12:40:34: Postdata RAW: {"list_folder": {"accounts": ["dbid:AAB2cfhttqMg1RjLLRlFzYWWoY6lUpWKsKo"]}, "delta": {"users": [189761154]}}
This is a sample call to my webhook. It gives the responsible accounts (where data has been changed) and the users who changed anything.
Due to this call you need to fetch changes. In my case the webhook is just a small php script which logs the calls to a file.

In the real case you need to have a javascript webhook which do a listfolder continue call for the given users.
I can´t help on this as i never setup a javascript server for dropbox or whatever i need to run.
Check the documentation.
https://www.dropbox.com/developers/reference/webhooks
 

peacemaker

Expert
Licensed User
Delta function of v.1 was OK, i guess, strange that it was changed in v.2, and now i do not understand how to use those "cursors" to compare files...
 
Last edited:

DonManfred

Expert
Licensed User
B4X:
dbxFiles.listFolder("",False,True,False,True,True)
lists all Files in the Dropbox. In my version the resultevent gives the latest Cursor in the Error value...
In my tests the given Cursor was a 750 Bytes long unique string.

You need to know/remember the dropboxId of the account you are actually using/requesting. And the latest cursor.
Use
B4X:
dbxUsers.CurrentAccount
to get the current Account.
B4X:
Sub dbxUsers_getCurrentAccount(account As FullAccount)
    Log($"dbxUsers_getCurrentAccount(${account})"$)
    kvs.Put("AccountID",account.AccountId) ' This is the ID of the Dropbox used. We want to track them so we need to remember this ID.
    Dim acc As String = account.Name
    Dim parser As JSONParser
    parser.Initialize(acc)
    Dim root As Map = parser.NextObject
    Dim abbreviated_name As String = root.Get("abbreviated_name")
    Dim familiar_name As String = root.Get("familiar_name")
    Dim surname As String = root.Get("surname")
    Dim given_name As String = root.Get("given_name")
    Dim display_name As String = root.Get("display_name")

    Log("Name? "&display_name)
    'Log("Name? "&acc.Get("display_name"))
    kvs.Put("AccountName",display_name)
    kvs.Put("AccountType",account.AccountType)
ListFolder results in an Event. The Lastest Cursor is used in the error-Value.

B4X:
Sub dbxFiles_listFolder(success As Boolean, content As List, error As String)
    Log($"dbxFiles_listFolders(${success}, ${content.Size}, ${error.Length} ->  ${error})"$)
    If error.Length = 750 Then
        Log("Cursor to KVS")
        kvs.Put("LatestCursor_"&loggedUserID,error) ' loggedUserID must contain the AccountID
    End If
    If content.Size > 0 Then
        For i = 0 To content.Size-1
            'Dim meta As Metadata = content.Get(i)
            'Log(meta.toString)
        Next
    End If
End Sub
At appstart(or when authentiucated to Dropbox) you now can use the latest stored Cursor and get the latest content (new Method in v0.42)
B4X:
        If kvs.ContainsKey("LatestCursor_"&loggedUserID) Then
            Dim latest As String = kvs.Get("LatestCursor_"&loggedUserID)
            Log("Latest Cursor = "&latest)
            dbxFiles.listFolderContinue(latest)
        End If
This results in a Event (new too)

B4X:
Sub dbxFiles_ListFolderContinue(content As List, cursor As String)
    Log($"dbxFiles_ListFolderContinue(${content.Size}, ${cursor})"$)

    If content.Size > 0 Then
        For i = 0 To content.Size-1
            Dim meta As Object = content.Get(i)
            Log(GetType(meta))
            If GetType(meta) = "com.dropbox.core.v2.files.FileMetadata" Then
                Dim filemeta As FileMetadata = meta
                Log($"FileMeta ${filemeta.Name}, ${filemeta.PathDisplay}"$)
            else if GetType(meta) = "com.dropbox.core.v2.files.FolderMetadata" Then
                Dim foldermeta As FolderMetadata = meta
                Log($"FolderMeta ${foldermeta.Name}, ${foldermeta.PathDisplay}"$)
            else if GetType(meta) = "com.dropbox.core.v2.files.DeletedMetadata" Then
                Dim deletedmeta As DeletedMetadata = meta
                Log($"DeletedMeta ${deletedmeta.Name}, ${deletedmeta.PathDisplay}"$)
            End If
            Log(meta)
        Next
    End If
    Log("LatestCursor to KVS")
    kvs.Put("LatestCursor_"&loggedUserID,cursor)
   
End Sub
As you can see here the result is parsed into different Objects as there may be different ones in the Result. DeletedMetadata is btw a new Object i wrapped to match the requirements here.
At the end the given Cursor (it is a new latest cursor) the cursor is updated in the kvs.

This Event tells you the latest changes.

I did the tests in my b4j version of the wrapper and in my b4j example. It looks good i think.

I expect it to work the same in the B4A Version. Note that i need to Update both and release them (not yet done).
 
Last edited:
Top