1
votes

I'm trying to use Google Firestore for the first time, authenticating with google api authentication. The first thing I'm doing is populating the database with a StartBatch with several Set methods, when I await the batch Task, it gives me this error:

Error: Status(StatusCode=PermissionDenied, Detail="Request had insufficient authentication scopes.") ;

I've found little about authenticating with google to connect to firestore. First I authenticate with this method using the secret provided by google console for my app:

    public async Task<GoogleOAuthState> GetUserCredentialAsync(string user = null, GoogleOAuthState oAuthState = null)
    {
        using (ClientSecretStream)
        {
            string credPath = System.Environment.GetFolderPath(
                System.Environment.SpecialFolder.Personal);

            if (oAuthState == null)
            {
                try
                {
                    var credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                        GoogleClientSecrets.Load(ClientSecretStream).Secrets,
                        _Scopes,
                        string.IsNullOrEmpty(user) ? "user" : user,
                        CTS.Token,
                        new FileDataStore(credPath, true));

                    return new GoogleOAuthState(credential, _AppName);
                }
                catch (Exception e)
                {
                    SetErrorMessage(e, "Error al intentar identificarse en google");
                    return null;
                }
            }
            else
            {
                try
                {
                    await GoogleWebAuthorizationBroker.ReauthorizeAsync(
                        oAuthState.Credential,
                        CTS.Token);
                    return oAuthState;
                }
                catch (Exception e)
                {
                    SetErrorMessage(e, "Error al intentar volver a identificarse en google");
                    return null;
                }
            }
        }
    }

Using the same scopes that are configured in my google console for the app (I use google drive in the same app):

            SheetsService.Scope.Spreadsheets
            DriveService.Scope.DriveFile
            DriveService.Scope.Drive
            DriveService.Scope.DriveAppdata
            DriveService.Scope.DriveMetadata
            "https://www.googleapis.com/auth/datastore"
            "https://www.googleapis.com/auth/cloud-platform"

GoogleOAuthState is just an object to hold and pass Credential and what not. After that I connect to firestore with this:

    public async Task ConnectDB(GoogleLogin.GoogleOAuthState oAuthState)
    {
        var channelCredentials = oAuthState.Credential.ToChannelCredentials();
        var channel = new Channel(FirestoreClient.DefaultEndpoint.ToString(), channelCredentials);
        var client = FirestoreClient.Create(channel);
        _DB = FirestoreDb.Create(Properties.Settings.Default.FirebaseProjectName, client);
    }

I saw that method in this question and thought it'd be the most reliable.

I've set firestore rules like this in the meanwhile:

service cloud.firestore {
match /databases/{database}/documents {
  match /{document=**} {
    allow read, write: if true;
    }
  }
}

The google authentication works ok, I can use google drive without problems. I've also added google as an authentication method in the firestore console, and added the app id(I'm not sure if this is really necessary).

I think I'm misunderstanding something... Is it even possible to do this? Or do I have to use a service account?

1
Use a sniffer like wireshark or fiddler. You are making a HTTP connection. The headers in the 1st request determine the parameter you are using and the parameters you are using are not correct. Capture the console app and compare the headers with your c# app. Then make the c# app headers look like the console app. - jdweng
Ok, take in mind that I'm an amateur, but... I have no idea of what you're talking about. The firestore and google apis are making the HTTP stuff, not me. Afaik I can not change the headers unless I use directly the REST api(which I don't use as you can see in the question). Also: "Capture the console app"? What? What "console app"? This isn't a console app, are you talking about the firestore web console or is it a fiddler thing (I've never used it before)? - Nox
You are still passing the api parameters which are added to the http message. There is something you are not setting correctly. By comparing a working google console will indicate what is wrong. Fiddler is a tool to capture messages sent/received over the internet. Some applications have built-in Fiddler Tools. You can also download for free a Fiddler to use in parallel with running you application. Fiddler will capture the http message sent and received to help debug issue. See : wiki.scn.sap.com/wiki/display/CPM/What+is+the+Fiddler+Tool - jdweng
Ok, I'll try it, thanks for clarify it. - Nox

1 Answers

-1
votes

Well, from what I've tested and read, It seems that it's not possible to sign to Firestore via oAuth from a desktop application: you use a service account or nothing. I'm not even sure if it's possible to sign from a desktop application at all, it's all mobile or web, nothing more.

Anyway, even with the service account, now I have another problem, so I'm opening another question.