OAuth 2.0 authorization for the Google Sheets API from an iOS device

I am aware that this is going to be a very specific issue, but here goes.

I’m working on a package that makes authorization and use of the Google Sheets API from Unity much easier, but once my application is built to an iOS device the OAuth 2.0 authorization stops working entirely. A quick break down of the OAuth 2.0 system it uses:

In order to perform both read and write requests from a Google spreadsheet, you must use OAuth 2.0 authorization. This requires you to assign an OAuth 2.0 credential on the Google Cloud Dashboard for your project, which gives you a .json file (or a .plist file for an iOS device) that contains the client secret information. It’s basically a set of special passwords to grant you permission to obtain an access token from Google, which lets you interact with the Google Sheets API as normal. The following code is what I have been using, and has been working fine up until now:

UserCredential credential;
string fileName = "credentials.json";

// load client secrets
using (var stream = new FileStream(Path.Combine(Application.streamingAssetsPath, fileName), FileMode.Open, FileAccess.Read))
{
    string credPath = "token.json";
    credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.FromStream(stream).Secrets, scopes, "user", CancellationToken.None, new FileDataStore(credPath, true)).Result;

    // create Google Sheets API service
    service = new SheetsService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = applicationName
    });
}

What this does is load the credentials file, obtain its client secrets information, and send it to Google to get the access token (called credential here). Using this token, it then starts a live service connected to a Google spreadsheet.

This process works well on desktop (and took a lot of headache to get working), but once built into an iOS device it stops working. Nothing I have tried has worked, it’s able to see the credentials file (I change fileName to reference the correct .plist file when building), but it seemingly can’t read it in .plist format, throwing a “Could not parse ‘<’” error. Converting the .plist to a .json lets it read it, but it seems to confuse the GoogleWebAuthorizationBroker and interpret it as a regular desktop credential, which doesn’t work either.

I’ve also tried simply entering the client secrets information directly as a ClientSecrets class, which works perfectly fine on desktop, but I seemingly can’t find a way to get it to function on iOS. It just keeps saying that I have no authorization to do that action, so I’m assuming it’s referring to the credentials not being set up correctly.

If there is anyone on this forum who has tackled the beast that is the Google Sheets API before, please help! There is so little information out there on the Google Sheets or Authorization APIs, let alone specifically for Unity. Practically none exists for iOS Unity apps using Google Sheets either. I’m completely stumped.

Who is giving you that complaint? If it’s the service endpoint perhaps you are not properly URL-escaping or MIME-encoding some part of your data.

If it’s not that, then…

Networking, UnityWebRequest, WWW, Postman, curl, WebAPI, etc:

https://discussions.unity.com/t/831681/2

https://discussions.unity.com/t/837672/2

And setting up a proxy can be very helpful too, in order to compare traffic:

https://support.unity.com/hc/en-us/articles/115002917683-Using-Charles-Proxy-with-Unity

Thank you for the reply Kurt! I’ve done some more debugging, and it turns out the issues were coming from the System.IO being unable to access a particular file location. That problem is seemingly solved, but now I have new exceptions being thrown.

So now when GoogleWebAuthorizationBroker.AuthorizeAsync() is called, it now throws this error:

System.AggregateException: One or more errors occurred. (Failed to launch browser with "[url info here]" for authorization; platform not supported.) ---> System.NotSupportedException: Failed to launch browser with "[more url info here]" for authorization, platform not supported.

So my best guess is that Unity is unable to open the web browser properly for some reason when on iOS. I’m not sure how to continue, any ideas?

No idea… if I need to open a browser I just do Application.OpenURL() but I don’t know if that would even remotely be useful to you in this token-give-me-assets context. Probably not, since you do need to GET the data in your program.

It’s kinda odd that it tries to open the browser; I wonder if that is something in your OS interpreting the URL as meaning the browser must be first opened, or perhaps some other auth step happening.

Perhaps ask in google support forums, or even the ios forum here on this board?