0
votes

I have a C# program that reads the computers specs and saves them to a Google FirestoreDB. In 95% of the computers, everything works fine. But some computers (can't find a common denominator) come back with the error:

Grpc.Core.RpcException: Status(StatusCode=Unavailable, Detail="failed to connect to all addresses")
grpc_status: 14

The environment variable GOOGLE_APPLICATION_CREDENTIALS has the correct path to the keyfile.json which has this content (Downloaded from google cloud console. Sensitive data removed):

{   "type": "service_account",   "project_id": "project-id",  
"private_key_id": "XXXXXXXXXXXX",   "private_key": "-----BEGIN PRIVATE
KEY-----XXXXXXXXXXXX---END PRIVATE KEY-----\n",   "client_email":
"[email protected]",   "client_id": "XXXXXX",  
"auth_uri": "https://accounts.google.com/o/oauth2/auth",  
"token_uri": "https://oauth2.googleapis.com/token",  
"auth_provider_x509_cert_url":
"https://www.googleapis.com/oauth2/v1/certs",  
"client_x509_cert_url":
"https://www.googleapis.com/robot/v1/metadata/x509/XXXXXX.iam.gserviceaccount.com"
}

Here's the C# code that saves the data to the FirestoreDB:

try
            {
                string GoogleCloudProjectId = "project-id";
                Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", AppDomain.CurrentDomain.BaseDirectory + "keyfile.json");
                FirestoreDb db = FirestoreDb.Create(GoogleCloudProjectId);

                DocumentReference docRef = db.Collection("inventory").Document(systemSpecs.ItemID);

                await await docRef.SetAsync(systemSpecs).ContinueWith(q =>
                {
                    if (q.IsCompleted && !q.IsFaulted)
                    {
                        MessageBox.Show("Added successfully to inventory.", "Ok", MessageBoxButton.OK, MessageBoxImage.Information);
                    }
                    return q;
                });
            }
            catch (Grpc.Core.RpcException rpcEx) {
                MessageBox.Show(rpcEx.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.GetType().ToString());
                MessageBox.Show("Error:\n\n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            finally
            {
                Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", null);
                Environment.Exit(0);
            }

Using the latest packages versions available from NuGet (Visual Studio):

Google.Api.Gax = v3.2.0
Google Api.Gax.Grpc = v3.2.0
Google Api.Gax.Grpc.GrpcCore = v3.2.0
Google.Cloud.Firestore = v2.3.0
Google.Cloud.Firestore.V1 = v2.2.0
Grpc.Auth = v2.34.0
Grpc.Core = v2.34.0
Grpc.Core.Api = v2.34.0

The computer has internet access (Tested with both wifi and wired connection). It pings fine google.com, accounts.google.com, oauth2.googleapis.com, www.googleapis.com. I also disabled the Windows Firewall, and this made no difference. This happens in computers running Windows 7 and Windows 10.

Using the same internet connection, other computers running the same program everything works fine.

Why is the GRPC call not working on some computers? Not sure what else I can check/try. Thanks!

1
I'm less familiar with gRPC with C# but you should consider bumping logging/tracing, see link, link. Is your server hosted on GCP? If so, you may want to also consider leveraging Cloud Debugger to get a better picture of the server exceptions. I wonder whether you're suffering either from a gRPC timeout and|or a timeout to Firestore? - DazWilkin
Slightly "unconventional" way to propagate Application Default Credentials. I think it's unrelated to your other issue. But, commonly, if you're running off-GCP, you'd populate GOOGLE_APPLICATION_CREDENTIALS in the shell before running the .NET process. If you're running on GCP, this value will be populated automatically for you. - DazWilkin
My suspicion is that there's a proxy involved that doesn't understand HTTP/2.0, or hasn't been configured on this machine - that's what I've seen in every other case of "failed to connect to all addresses". - Jon Skeet

1 Answers

0
votes

It turned out that the problem was that the timezone was not correct in the computers where that were presenting the problem.

This would have been much easier to identify if the error message was more descriptive, since the computers did have network connectivity to Google's servers.