4

I am trying to connect to the new Google Analytics Data api using C# to request data from the new google analytics GA4. The only sample i can find is Quickstart client libraries .net This does work but it uses a service account. The cloud .net client library google-cloud-dotnet only has examples for using a service account.

When i try to pass it desktop app credentials for using Oauth" authorization i get

Error creating credential from JSON. Unrecognized credential type.

using System;
using System.Threading;
using System.Threading.Tasks;
using Google.Analytics.Data.V1Beta;

namespace GoogleAnalyticsExamplesData
{
    class Program
    {
        private const string PropertyId = "250796939";
        private const string PathToCreds = @"C:\dev\ServiceAccountCred.json";

        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            // Check whether the environment variable exists.
            var environmentVariable = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");
            // If necessary, create it.
            if (environmentVariable == null)
                Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", PathToCreds);

            await SampleRunReport(PropertyId);
        }
        
        static async Task SampleRunReport(string propertyId = "YOUR-GA4-PROPERTY-ID")
        {
            // Using a default constructor instructs the client to use the credentials
            // specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
            var client = await BetaAnalyticsDataClient.CreateAsync(CancellationToken.None);

            var request = new RunReportRequest
            {
                Property = "properties/" + PropertyId,
                Dimensions = {new Dimension {Name = "date"},},
                Metrics = {new Metric {Name = "totalUsers"}, new Metric {Name = "newUsers"}},
                DateRanges = {new DateRange {StartDate = "2021-04-01", EndDate = "today"},},
            };

            var response = await client.RunReportAsync(request);


            Console.WriteLine("Report result:");

            foreach (var row in response.Rows)
            {
                Console.WriteLine(
                    $"{row.DimensionValues[0].Value}, {row.MetricValues[0].Value}, {row.MetricValues[1].Value}");
            }
        }
    }
}

Links to Google.Analytics.Data.V1Beta Web client credentials, desktop credentials

oguz ismail
  • 1
  • 16
  • 47
  • 69
Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449

1 Answers1

1

After several hours of digging around i found that you can use ICredential using a builder. This works with a Desktop app credentials, for installed applications.

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Google.Analytics.Data.V1Beta;
using Google.Apis.Auth.OAuth2;

using Google.Apis.Util.Store;

namespace GoogleAnalyticsExamplesData
{
    class Program
    {
        private const string PropertyId = "250796939";
        private const string PathToCreds = @"C:\dev\credentials.json";

        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");   
          

            await SampleRunReport(PropertyId);
        }

        static async Task SampleRunReport(string propertyId = "YOUR-GA4-PROPERTY-ID")
        {
            // Using a default constructor instructs the client to use the credentials
            // specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
            //var client = await BetaAnalyticsDataClient.CreateAsync(CancellationToken.None);

            BetaAnalyticsDataClient client ;
            await using (var stream = new FileStream(PathToCreds, FileMode.Open, FileAccess.Read))
            {
                // Requesting Authentication or loading previously stored authentication for userName
                var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
                    new[] { "https://www.googleapis.com/auth/analytics.readonly"},
                    "userName",
                    CancellationToken.None,
                    new FileDataStore("credPath", true)).Result;
                
                client = await new BetaAnalyticsDataClientBuilder
                {
                    TokenAccessMethod = credential.GetAccessTokenForRequestAsync
                }.BuildAsync();
            }

            var request = new RunReportRequest
            {
                Property = "properties/" + PropertyId,
                Dimensions = {new Dimension {Name = "date"},},
                Metrics = {new Metric {Name = "totalUsers"}, new Metric {Name = "newUsers"}},
                DateRanges = {new DateRange {StartDate = "2021-04-01", EndDate = "today"},},
            };

            var response = await client.RunReportAsync(request);


            Console.WriteLine("Report result:");

            foreach (var row in response.Rows)
            {
                Console.WriteLine(
                    $"{row.DimensionValues[0].Value}, {row.MetricValues[0].Value}, {row.MetricValues[1].Value}");
            }
        }
    }
}
Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • 1
    Hey, I found your post useful. I am just starting out on a project with GA 4 using the .net client libraries. But I am wondering why you didn't want to use a service account and chose OAuth instead? Also, I was able to connect with code similar to your first post after creating a service account. Just curious about the reasoning. – MattoMK Dec 08 '22 at 18:41
  • 1
    A service account will only give you access to an account you the developer control, as you need to add the service account as a user in Google analytics Web ui. In this instance we want to request permission of the user to access their google analytics account not ours. For that you need to use Oauth2, and request consent of the user. – Linda Lawton - DaImTo Dec 09 '22 at 07:44
  • 1
    Ah ok, that makes perfect sense. Since in my context we control the account I should be fine with the SA. Thanks for your posts on this topic, a lot of them have been very helpful. – MattoMK Dec 09 '22 at 14:54