Oranutachi
Oranutachi

Reputation: 1279

Error connecting to Google Drive API (Swift 5)

I want to connect to the Google Drive API in my application in order to display a list of user files and be able to download them to the device. I am following this sample Integrate Google Drive to iOS app

I connected Google SDK and successfully authorize the user. However I can't get the list of its files in any way. I keep getting the following error:

"Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."

I checked my app and settings in the Google Console many times, did everything step by step, but still couldn't solve this problem. Has anyone experienced the same problem?

My code and screenshots:

//class AppDelegate...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        GIDSignIn.sharedInstance().clientID = "Me client ID"
        return true
}

//class myVC: GIDSignInDelegate...
override func viewDidLoad() {
        super.viewDidLoad() 
        GIDSignIn.sharedInstance().presentingViewController = self
        GIDSignIn.sharedInstance().delegate = self
        GIDSignIn.sharedInstance().scopes = [kGTLRAuthScopeDrive]
        GIDSignIn.sharedInstance().restorePreviousSignIn()
}

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
              withError error: Error!) {
        if let error = error {
            print("Google autorization error: \(error.localizedDescription)")
            return
        }
        guard let token = user.authentication.accessToken else { return }
    SourceAuthorizationStateManager.shared.addAuthorizedSource(.googleDrive)
    
    let fullName = user.profile.name
    print("Google authorization successful. User name: \(fullName ?? "Error: no user name")\nUser token: \(token)")
}

//class GoogleDriveFileListSource...
private var fileListTicket: GTLRServiceTicket?
var files: [FileModelProtocol] {
        guard let files = fileList?.files else { return [] }
        return files.map { GoogleDriveFileModel($0) }
}

lazy var driveService: GTLRDriveService = {
    let service = GTLRDriveService()
    service.shouldFetchNextPages = true
    service.isRetryEnabled = true
    return service
}()

func fetchFileList(path: String?, _ completion: @escaping () -> Void) {
        let query = GTLRDriveQuery_FilesList.query()
        query.fields = "kind,nextPageToken,files(mimeType,id,kind,name,webViewLink,thumbnailLink,trashed)"
        
        fileListTicket = driveService.executeQuery(query,
                                                   completionHandler: { [weak self] (_, resultObject, error) in
                                                    if let error = error {
                                                        debugPrint("driveService.executeQuery error: \(error.localizedDescription)")
                                                        return
                                                    }
                                                    
                                                    guard let self = self,
                                                        let fileList = resultObject as? GTLRDrive_FileList else { return }
                                                    
                                                    self.fileList = fileList
                                                    self.fileListTicket = nil
                                                    
                                                    completion()
     })
}

API is enable The limit is not exhausted Authorization successful

Upvotes: 3

Views: 1276

Answers (2)

Oranutachi
Oranutachi

Reputation: 1279

Solved. Thanks to everyone who helped. All I had to do was transfer the user authentication status to driveService and import GTMSessionFetcher to my files.

var googleUser: GIDGoogleUser?
class myVC: GIDSignInDelegate {
...
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
              withError error: Error!) {
        if let error = error {
            print("Google autorization error: \(error.localizedDescription)")
            return
        }
        guard let token = user.authentication.accessToken else { return }
    SourceAuthorizationStateManager.shared.addAuthorizedSource(.googleDrive)
    googleUser = user   //Here I have saved the current user

    let fullName = user.profile.name
    print("Google authorization successful. User name: \(fullName ?? "Error: no user name")\nUser token: \(token)")
}
}

class GoogleDriveFileListSource {
...
lazy var driveService: GTLRDriveService = {
    let service = GTLRDriveService()
    if let user = googleUser {
    service.authorizer = user.authentication.fetcherAuthorizer() //Here I passed the status
    }
    service.shouldFetchNextPages = true
    service.isRetryEnabled = true
    return service
}()
}

Now the code looks not very nice, I will think about how to improve it. But this already works, I get the list of user's files.

Upvotes: 2

Linda Lawton - DaImTo
Linda Lawton - DaImTo

Reputation: 116938

"Daily Limit for Unauthenticated Use Exceeded.

Means that you are not authorized. Calls to Google APIs that expose private user data must include an authorization header bearer token containing an access token.

You appear to be sending something called a user token which I dont think its the same as setting the authorization header.

debuging attempt

Note, I have never owned an apple device. I am not an Ios or swift developer. I have been working with the Google APIs and library for years.

From what i can see you are calling

fileListTicket = driveService.executeQuery(query,

While the tutorial you are following calls

self.service.executeQuery(query)

You didnt change the delicate set up

GIDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().uiDelegate = self

Why did you change it?

Upvotes: 1

Related Questions