Bug 52906 - Visual Studio hangs indefinitely when setting google-services.json file Build Action to GoogleServicesJson
Summary: Visual Studio hangs indefinitely when setting google-services.json file Build...
Status: RESOLVED DUPLICATE of bug 53817
Alias: None
Product: Components
Classification: Xamarin
Component: Visual Studio Integration ()
Version: N/A
Hardware: PC Windows
: High major
Target Milestone: ---
Assignee: Jon Dick
URL:
: 52842 ()
Depends on:
Blocks:
 
Reported: 2017-02-28 17:27 UTC by Jon Douglas [MSFT]
Modified: 2017-06-20 09:08 UTC (History)
14 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED DUPLICATE of bug 53817

Description Jon Douglas [MSFT] 2017-02-28 17:27:41 UTC
*Description:

I am reporting this bug on behalf of multiple customers in the Xamarin Forum:

There have been multiple reports regarding various customer's Visual Studio IDE hanging indefinitely when setting the "Build Action" of their "google-services.json" file to "GoogleServicesJson". You can refer to a whole forum thread on this topic here:

https://forums.xamarin.com/discussion/88814/since-adding-google-services-json-for-push-notifications-visual-studio-frequently-hangs

For those not familiar, google-services.json is a credentials file that is created from the Firebase Console. You can overview these details here:

https://developer.xamarin.com/guides/android/application_fundamentals/notifications/firebase-cloud-messaging/

The problematic Build Action that is being set is found in the following targets file:

https://github.com/xamarin/GooglePlayServicesComponents/blob/c236efaef4a4479e0cf7680a7212adb495f53723/basement/buildtasks/Xamarin.GooglePlayServices.Basement.targets

The actual code of this execution is found here:

https://github.com/xamarin/GooglePlayServicesComponents/blob/c236efaef4a4479e0cf7680a7212adb495f53723/basement/buildtasks/ProcessGoogleServicesJson.cs#L34

*Reproduction:

At this time, I am personally unable to reproduce on Xamarin 4.3.0.784 (73f58d6) and previous versions as I have used Firebase extensively.

I will be attempting to get community members to upload main thread stacks and diagnostic build output to assist this bug further. 

*Version Information

Customers on the following versions have noted the hangs:

Xamarin 4.2.2.11 (00fa5cc)
Xamarin 4.3.0.738 (9473a85)
Xamarin 4.3.0.784 (73f58d6)
Comment 1 crypted 2017-03-02 09:15:33 UTC
This is giving nightmare. Any workaround for this ????
Comment 2 Jose Gallardo 2017-03-02 13:15:20 UTC
*** Bug 52842 has been marked as a duplicate of this bug. ***
Comment 3 Jose Gallardo 2017-03-02 13:26:47 UTC
Hi, 

I'm sorry for the inconveniences this issue is causing. We're already investigating.

I'm updating Target Milestone and importance for now. Any update will be shared in this bug report.

Thanks for reporting.
Comment 4 Josh Russo 2017-03-02 13:39:37 UTC
In case someone misses the work-around in the forum post above, it can be found here 

https://forums.xamarin.com/discussion/comment/250262#Comment_250262
Comment 5 Jon Dick 2017-03-02 14:07:18 UTC
This custom build task currently takes the json file and creates two resource files with values parsed from the JSON.  If you want to work around this for now, you can do the following:

1. Build one time with the google-services.json file. 
2. Copy the obj/Debug/res/values/goog_svcs_json.xml file (if it exists) into your project's Resources/values/ folder
3. Copy the obj/Debug/res/xml/global_tracker.xml file (if it exists) into your project's Resources/xml/ folder
4. Remove the google-services.json file from your project.
Comment 6 Paul Sinnema 2017-03-02 14:52:56 UTC
I've found this to be a good work around for me.

- Remove the google-services.json file from you project (or set the build action to 'none') and copy the values needed in the code below to a settings class.

        private FirebaseApp m_App;

        private void InitFirebase()
        {
            if (m_App == null)
            {
                FirebaseOptions options = new FirebaseOptions.Builder()
                    .SetApplicationId(Settings.FirebaseAppId)
                    .SetApiKey(Settings.FirebaseApiKey)
                    .SetGcmSenderId(Settings.GcmSenderId)
                    .SetDatabaseUrl(Settings.FirebaseDatabaseUrl)
                    .SetStorageBucket(Settings.FirebaseStorageBucket)
                    .Build();

                m_App = FirebaseApp.InitializeApp(Android.App.Application.Context, options);
            }
        }

My Settings class looks like this:


    internal class Settings
    {
        public static string FirebaseApiKey { get { return "AIzaSyCOzWpRQ4yOQ-Zzxxxxxxxxxxxxxxxxxxx"; } }
        public static string FirebaseAppId { get { return "<package name>"; } }
        public static string FirebaseDatabaseUrl { get { return "https://<your url>"; } }
        public static string FirebaseStorageBucket { get { return "<your bucket name>"; } }
        public static string GcmSenderId { get { return "<projectid>"; } }
        public static string GcmProjectId { get { return "<your name>-xxxxx"; } }
    }
Comment 7 Paul Sinnema 2017-03-02 16:44:33 UTC
And here's an even better work around. I've created a T4 template that will generate the settings class for you. You could even generate the initialisation from my previous work arround:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Runtime" #>
<#@ assembly name="Microsoft.CSharp" #>
<#@ assembly name="$(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Runtime" #>
<#@ import namespace="Microsoft.CSharp" #>
<#@ import namespace="Newtonsoft.Json" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>

<#
	string jsonPath = Path.Combine(Host.ResolveAssemblyReference("$(SolutionDir)"), "BOABackgroundService", "BOABackgroundService.Droid", "google-services.json");

	ImportJson(jsonPath);

#>
	/* jsonPath:              <#=jsonPath #>
       GcmSenderId:           <#=GcmSenderId #>
       FirebaseApiKey:		  <#=FirebaseApiKey #>
       FirebaseDatabaseUrl:   <#=FirebaseDatabaseUrl #>
       FirebaseStorageBucket: <#=FirebaseStorageBucket #>
       GcmProjectId:          <#=GcmProjectId #>
	*/
<#

				
 #>

using System.IO;

namespace BOABackgroundService.Classes
{
    public static class FirebaseSettings
    {
		public static string ProjectDir { get { return Path.GetDirectoryName("$(ProjectDir)"); } }
        public static string FirebaseApiKey { get { return "<#=FirebaseApiKey #>"; } }
        public static string FirebaseAppId { get { return "nl.natuurnetwerk.boatan"; } }
        public static string FirebaseDatabaseUrl { get { return @"<#=FirebaseDatabaseUrl #>"; } }
        public static string FirebaseStorageBucket { get { return "<#=FirebaseStorageBucket #>"; } }
        public static string GcmSenderId { get { return "<#=GcmSenderId#>"; } }
        public static string GcmProjectId { get { return "<#=GcmProjectId #>"; } }
    }
}

<#+
	void ImportJson(string filename)
	{
		dynamic googleServices;
		StreamReader file = File.OpenText(filename);
		string text = file.ReadToEnd();
		googleServices = JsonConvert.DeserializeObject<dynamic>(text);
		GcmSenderId = googleServices.project_info.project_number;
		FirebaseApiKey = googleServices.client[0].api_key[0].current_key;
		FirebaseDatabaseUrl = googleServices.project_info.firebase_url;
		FirebaseStorageBucket = googleServices.project_info.storage_bucket;
		GcmProjectId = googleServices.project_info.project_id;
	}

	string GcmSenderId { get; set; }
	string FirebaseApiKey { get; set; }
	string FirebaseDatabaseUrl { get; set; }
	string FirebaseStorageBucket { get; set; }
	string GcmProjectId { get; set; }
#>
Comment 9 Brendan Zagaeski (Xamarin Team, assistant) 2017-03-23 00:52:19 UTC
I was able to replicate this issue locally today in a small sample test case and was able to verify candidate fix from Bug 52967, Comment 23 in that scenario.

I filed a new bug to provide a clean description of the current status of that particular issue.  I will accordingly mark this bug as a duplicate for bookkeeping.  If any user sees similar performance issues after updating to Xamarin.Build.Download 0.4.3-beta2 or higher, please file a new bug report with as many details as possible about what might be different in your project compared to the test case on Bug 53817.  If possible, please also collect a sample minidump or two from the busy instance of Visual Studio (similar to Bug 53817, Comment 1).  Thanks!

*** This bug has been marked as a duplicate of bug 53817 ***