Android Question Problems with oAuth

mw71

Active Member
Licensed User
Longtime User
hi,

i have trouble with oAuth for Google Drive (because it is no longer possible to use WebView for oAuth)

I have
- import this Class: https://www.b4x.com/android/forum/threads/class-b4x-google-oauth2.79426/
- add Manifest
- generate OAuth Client ID
- use Code:
B4X:
Dim oAuth As GoogleOAuth2
Dim scope As String
Dim clientID As String

scope = "https://www.googleapis.com/auth/drive"
clientID = "xxx-xxxxxxxl.apps.googleusercontent.com"

oAuth.Initialize(Me,"oauth",clientID,scope)

wait for Init finisch...

B4X:
oAuth.GetAccessToken

the oAuth Page is Display, User allowed Access, no Access Token will display? Browser open the Google Page.
The CallFromResume will not be called (in Debug mode)??

please Help :)
 

Mikonios

Active Member
Licensed User
Longtime User
Hi again "mw71". We have other problem with App migrated.

With old versión 3.82 and WebView, the request ::
h.Download2("https://www.googleapis.com/drive/v2/files", _
Array As String("access_token", myToken, _
"q","trashed=false"))

return all files aprox 590, and with all fields ::

{
"kind": "drive#user",
"displayName": "...............",
"isAuthenticatedUser": false,
"permissionId": "02773.........638123",
"emailAddress": "[email protected]"
}
],
"lastModifyingUserName": "..............",
"lastModifyingUser": {
"kind": "drive#user",
"displayName": "..................",
"isAuthenticatedUser": false,
"permissionId": "02773............8123",
"emailAddress": "[email protected]"
},
"capabilities": {
"canCopy": true,
"canEdit": true
},
"editable": true,
"copyable": true,
"writersCanShare": true,
"shared": true,
"explicitlyTrashed": false,
"appDataContents": false,
"headRevisionId": "0B679z.....................................S9yTm5jPQ",
"spaces": [
"drive"
]
}

Now with new versión 7.30 and Oauth, in v2 API, result are 100 records max !!!!
Wtih 7.30 and Oauth in v3 API the same, 100 records max, and minus fields

h.Download2("https://www.googleapis.com/drive/v3/files", _
Array As String("access_token", myToken, _
"corpora", "user", _
"q","mimeType!='application/vnd.google-apps.folder' and trashed=false"))

"kind": "drive#fileList",
"nextPageToken": "~!!~AI9FV7T_..........................VRoc-o6npHHg==",
"incompleteSearch": false,
"files": [
{
"kind": "drive#file",
"id": "0B55U0................ncjJwQW8",
"name": "............db",
"mimeType": "application/x-www-form-urlencoded"
},
{
"kind": "drive#file",
"id": "0BypHY..................jZGZMYTA",
"name": "..................db",
"mimeType": "application/x-www-form-urlencoded"
},
{
"kind": "drive#file",
"id": "0B_r-2.......................bTBmSUE",
"name": "............db",
"mimeType": "application/x-www-form-urlencoded"
},
{
"kind": "drive#file",
"id": "0B_r-2l....................KLUNna3c",
"name": ".....................db",
"mimeType": "application/x-www-form-urlencoded"
},

We need a result with maxResults = 1000 and fields=*
The api to request is indiferent.
Can you help us with both problems ???

Thank you very mutsh in advance !!!!
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
This is how the Api works.
It is similar in Dropbox Api.

If the result contains a "nextPageToken" then you need to use this token to get the next 100 results.
If the result contains a nextPageToken then you need to use this token to get the next 100 results.
and so on.

See Drive Api documentation for detailed informations.
 
Upvote 0

Mikonios

Active Member
Licensed User
Longtime User
Hi DonManfred.

What we do not understand is that in the previous version it worked in one way, and now it works in a totally different one, when the query is exactly the same. Why ???
h.Download2("https://www.googleapis.com/drive/v2/files", _
Array As String("access_token", myToken, _
"q","trashed=false"))

We see through the Google documentation that it is possible to do it:::

https://developers.google.com/drive/v2/reference/files/list
Optional query parameters
maxResults integer
Maximum number of children to return. Acceptable values are 0 to 1000, inclusive. (Default: 100)

and https://stackoverflow.com/questions/39771329/drive-rest-api-not-giving-more-than-100-results
say the same::
FilesResource.ListRequest request = service.Files.List(); request.MaxResults = 1000; FileList files = request.Execute();

and https://stackoverflow.com/questions/41137628/how-to-get-full-file-get-response-from-google-drive-v3 we see GET /drive/v3/files/0B5pJkOVaKccEVEsybFA2WjJjQ1k?access_token={Token}&fields=*

Our problem is the sintax and make both at the same time with only one API. (v2 or v3)
Do you know this sintaxis DonManfred ??
Have you done any testing and it worked ???
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
You can try just what i suggested. Using the pagetoken

B4X:
h.Download2("https://www.googleapis.com/drive/v2/files", _
Array As String("access_token", myToken, _
"q","trashed=false"))

So, if you get the result and it contains a pageToken (like in your example) then you should do another call to get the next results.

Based on the documentation
https://developers.google.com/drive/v3/web/search-parameters

i would try to use

B4X:
h.Download2("https://www.googleapis.com/drive/v2/files", _
Array As String("access_token", myToken, _
"q","trashed=false","pageToken",nextpageToken))
where nextpageToken should contain the token from the last result... It is worth a try :)
 
Upvote 0

Mikonios

Active Member
Licensed User
Longtime User
h.Download2("https://www.googleapis.com/drive/v2/files", _
Array As String("access_token", myToken, _
"q","maxResults=1000 and fields=* and trashed=false"))

With this syntax it is not necessary to exploit new tokens.
The result will contains all records, and will contains all fields.
But the syntax does not work !!!
Do you know how to write ???
 
Upvote 0

Mikonios

Active Member
Licensed User
Longtime User
Ok.
This is the first solution (sintax solution) to no exploit all token "nextpage"::
(And working)

h.Download2("https://www.googleapis.com/drive/v2/files", _
Array As String("access_token", myToken, _
"maxResults", "1000", _
"q","trashed=false"))


''' "fields", "*", _

Only remain all fields.
If someone knows how to do it or has already done it, please send a solution
 
Upvote 0

Mikonios

Active Member
Licensed User
Longtime User
Hola "mw71"
Another problem we have with the module, is that sometimes it identifies the user well with yours credentials, and the process works and end correctly. And other times it does not identify the user, leaving the process stopped and we do not know how to capture the error.

Where is the return to capture this error ??
Thack you in advance .

oAuth TestConnect
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials"
}
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
It looks like the token has to be renewed.
TestConnect should do this automatically.

B4X:
Sub TestConnect
    Log("oAuth TestConnect")
   
    ti.Valid=False
   
'request FileList
    Dim h_tc As HttpJob
    h_tc.Initialize("", Me)
    h_tc.Download2("https://www.googleapis.com/drive/v3/files", _
         Array As String("access_token", ti.AccessToken, _
                         "corpora", "user", _
                         "q","mimeType!='application/vnd.google-apps.folder' and trashed=false"))
    Wait For (h_tc) JobDone(h_tc As HttpJob)
   
    If h_tc.Success Then
'FileLliste receive, TestConecct success 
        Log(h_tc.GetString)
        ti.Valid=True
    Else
        Log("OAuth, Getting access token from REFRESH token in TestConnect")
        Dim j_rt As HttpJob
        j_rt.Initialize("", Me)
        j_rt.PostString("https://www.googleapis.com/oauth2/v4/token", _
        $"refresh_token=${ti.RefreshToken}&client_id=${mClientId}&grant_type=refresh_token&redirect_uri=${packageName & ":/oath"}"$)

        Wait For (j_rt) JobDone(j_rt As HttpJob)

        If j_rt.Success Then
            Log("OAuth TestConnect, Refresh access token Success")
           
            Dim jp As JSONParser
            jp.Initialize(j_rt.GetString)
            Dim m As Map = jp.NextObject
            ti.AccessExpiry = DateTime.Now + m.Get("expires_in")
            ti.AccessToken = m.Get("access_token")
            If m.ContainsKey("refresh_token") Then ti.RefreshToken = m.Get("refresh_token")
            ti.Valid = True
            SaveToken
        Else
            Log("OAuth TestConnect, Refresh Token ERROR")
        End If
        j_rt.Release       
    End If
   
    h_tc.Release
    CallSubDelayed3(mTarget, mEventName & "_TestFinish", ti.Valid, ti)
End Sub
 
Upvote 0

Mikonios

Active Member
Licensed User
Longtime User
True. We make modification and now, work perfctly.
Thank you very mutch !!!

B4X:
Sub X00_GdLst()
    'Csr.LogMemory1("   X00_GdLst.Entra:         (R." & RetryCon & ")", "1")
   
    oauth2.GetAccessToken
    Wait For OAuth2_AccessTokenAvailable (Success As Boolean, Token As String)
    If Success = False Then
        ToastMessageShow("Error accessing account.", True)
        Return
    Else
       
        myToken=Token
        oauth2.TestConnect
        Wait For OAuth2_TestFinish(Erfolg As Boolean)
       
        If EstaConectado Then
            'X0_GdLst
            X01_GetFileList("")
        Else
            If RetryCon <= 3 Then
                RetryCon = RetryCon + 1
                Csr.LogMemory1("   X00_GdLst.RetryCon:         (R." & RetryCon & ")", "1")
                X00_GdLst
            Else
                X55_GDLstSale("   X00_GdLst. Many.RetryCon(" & RetryCon & ")")
            End If
        End If
        '''X55_GDLstSale("   X00_GdLst.NoConecction")
    End If
   
End Sub
 
Upvote 0
Top