Version: 9.3.0.22 (Visual Studio Enterprise)
Microsoft Windows 10 Enterprise, 64x
71.1610.0-preview6
When I used both packages in same app, the FirebaseAuth method always is null, and I cant麓
use the Auth method of firebase Auth. Installing only Firebase Auth, works fine.
I tried with all firebase version's preview1 to preview6, and doesn麓t work Messaging with Auth.
I encountered this issue as well, after looking into it I think the issue is caused by the firebase service com.google.firebase.components.ComponentDiscoveryService being defined multiple times in the AndroidManifest.xml file instead of being merged into a single definition. Both the firebase.auth and the firebase.iid packages provide classes to be used by the ComponentDiscoveryService (firebase.iid is a dependency of firebase.messaging). These are added to the AndroidManifest.xml separately, and it seems that when a service is defined multiple times in the AndroidManifest, Android only uses the last definition and ignores earlier definitions that have the same service name. So the AndroidManifest ends up containing the following service definitions:
<service android:name="com.google.firebase.components.ComponentDiscoveryService" android:exported="false">
<meta-data android:name="com.google.firebase.components:com.google.firebase.auth.FirebaseAuthRegistrar" android:value="com.google.firebase.components.ComponentRegistrar" />
</service>
<service android:name="com.google.firebase.components.ComponentDiscoveryService" android:exported="false">
<meta-data android:name="com.google.firebase.components:com.google.firebase.iid.Registrar" android:value="com.google.firebase.components.ComponentRegistrar" />
</service>
Since the definition with FirebaseAuthRegistrar appears first, that definition ends up getting ignored and only the firebase.iid.Registrar class is registered for initialization.
As a workaround I tried adding a custom build task to merge the meta-data entries for any definitions of firebase.components.ComponentDiscoveryService, the generated service definition is shown below.
<service android:name="com.google.firebase.components.ComponentDiscoveryService" android:exported="false">
<meta-data android:name="com.google.firebase.components:com.google.firebase.auth.FirebaseAuthRegistrar" android:value="com.google.firebase.components.ComponentRegistrar" />
<meta-data android:name="com.google.firebase.components:com.google.firebase.iid.Registrar" android:value="com.google.firebase.components.ComponentRegistrar" />
</service>
After this change the Firebase.Auth and Firebase.Iid instances are initialized successfully and the Firebase.Auth instance is no longer null.
That was fast! Thanks mfarrell34. I tested creating a custom build task, and the results it was expected. All doit merge the services mentioned above.
Issue #234 is also in need of a custom build task.
@charlitos2 @mfarrell34
We're starting to work on the buildtarget, we're planning to execute it on this "trigger"
BeforeTargets="_CreateBaseApk"
.
Would you be able to share the one you wrote to solve this issue?
Sure, this is the build task:
public class FixFirebaseComponentDiscoveryServiceTask : Microsoft.Build.Utilities.Task {
[Required]
public string TargetManifestFilePath { get; set; }
private XDocument doc;
private XNamespace android = "http://schemas.android.com/apk/res/android";
private XElement firstFirebaseComponentServiceNode = null;
private HashSet<string> componentRegistrarsInFirstNode = new HashSet<string>();
static readonly string ComponentServiceName = "com.google.firebase.components.ComponentDiscoveryService";
static readonly string ComponentRegistrarAttributeValue = "com.google.firebase.components.ComponentRegistrar";
public override bool Execute() {
try {
int duplicateCount = 0;
/* We check for multiple ComponentServiceName service definitions, a reference is stored to the first one encountered and then
if any additional nodes are encountered we add all of their components to the first node and then delete all of the ComponentServiceName
nodes after the first, this is because Android doesn't support multiple service definitions in the same <Application> node */
doc = XDocument.Load(TargetManifestFilePath);
var q = from node in doc.Descendants("service")
let serviceName = node.Attribute(android + "name")
where serviceName != null && serviceName.Value == ComponentServiceName
select node;
q.ToList().ForEach(x => {
var children = from childNode in x.Descendants("meta-data")
let childValue = childNode.Attribute(android + "value")
let childName = childNode.Attribute(android + "name")
where childValue != null && childName != null && childValue.Value == ComponentRegistrarAttributeValue
select childNode;
if (firstFirebaseComponentServiceNode is null) {
firstFirebaseComponentServiceNode = x;
children.ToList().ForEach(chld => {
if (!componentRegistrarsInFirstNode.Contains(chld.Attribute(android + "name").Value)) {
componentRegistrarsInFirstNode.Add(chld.Attribute(android + "name").Value);
} else {
chld.Remove();
}
});
} else {
++duplicateCount;
children.ToList().ForEach(chld => {
if (!componentRegistrarsInFirstNode.Contains(chld.Attribute(android + "name").Value)) {
firstFirebaseComponentServiceNode.Add(chld);
componentRegistrarsInFirstNode.Add(chld.Attribute(android + "name").Value);
}
});
x.Remove();
}
});
doc.Save(TargetManifestFilePath);
if (duplicateCount > 0) {
Log.LogMessage("Merged " + duplicateCount.ToString() + " duplicate " + ComponentServiceName + " services into single node");
} else {
Log.LogMessage("No duplicate " + ComponentServiceName + " services were present in AndroidManifest");
}
return true;
} catch (Exception ex) {
Log.LogError("Encountered error: " + ex.Message);
}
return false;
}
}
And this is how I use it as a workaround:
<Target Name="_FixFirebaseComponentDiscoveryServiceTask" AfterTargets="_GenerateJavaStubs" BeforeTargets="_ReadAndroidManifest">
<FixFirebaseComponentDiscoveryServiceTask TargetManifestFilePath="$(IntermediateOutputPath)android\AndroidManifest.xml" />
</Target>
Thx @mfarrell34 !
Here's the one we ended up writing with @GuillaumeSE and @jeremiethibeault
<Project>
<Target Name="FirebasePerfTask" BeforeTargets="_CreateBaseApk">
<_RewriteManifest Path="$(IntermediateOutputPath)android\AndroidManifest.xml" />
</Target>
<UsingTask TaskName="_RewriteManifest" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<Path ParameterType="System.String" Required="True" />
</ParameterGroup>
<Task>
<Using Namespace="System.Text.RegularExpressions" />
<Code Type="Fragment" Language="cs"><![CDATA[
//
// This is a workaround for bug https://github.com/xamarin/GooglePlayServicesComponents/issues/216
// where multiple <service ComponentDiscoveryService> are being overwritten in the AndroidManifest.xml
// by the last XML definition instead of being merged into a single definition.
//
// The solution is to capture all services named ComponentDiscoveryService from the AndroidManifest.xml
// before it is used to create the Android APK. If there are many ComponentDiscoveryService, replace
// all definitions with an empty string except the last one which will be used as the merged service.
// Simply put the content of all services into this one to get a final merged service.
//
// By doing so, all components are properly registered and we no longer have NullReferenceExceptions.
// This will need to be fixed in Xamarin.Android.
//
var manifest = File.ReadAllText(Path);
var matches = Regex.Matches(manifest, "(<service android:name=\"com\\.google\\.firebase\\.components\\.ComponentDiscoveryService\").*?(<\\/service>)", RegexOptions.Singleline);
// There are multiple ComponentDiscoveryService definitions, we will need to merge them.
if (matches.Count > 1)
{
var newManifest = manifest;
var serviceContent = new List<string>();
for (var i = 0; i < matches.Count; i++)
{
var m = matches[i];
// Capture the content of the service to merge it later with all the other ones.
var innerMatches = Regex.Matches(m.Value, "<service[\\s\\S]*?>([\\s\\S]*?)<\\/service>");
if (innerMatches.Count > 0)
{
var firstMatch = innerMatches[0];
if (firstMatch.Groups.Count > 1)
{
var capture = innerMatches[0].Groups[1].Value;
serviceContent.Add(capture);
}
}
// This is not the last occurrence, remove it from the AndroidManifest.
if (i < matches.Count - 1)
{
newManifest = newManifest.Replace(m.Value, "");
}
// This is the last occurrence, use it to merge all the service definitions.
else
{
var lastContent = serviceContent[serviceContent.Count - 1];
var updatedContent = string.Join("\n", serviceContent);
newManifest = newManifest.Replace(lastContent, updatedContent);
}
}
// Replace the AndroidManifest.
File.WriteAllText(Path, newManifest);
}
]]></Code>
</Task>
</UsingTask>
</Project>
I encountered this issue as well, after looking into it I think the issue is caused by the firebase service com.google.firebase.components.ComponentDiscoveryService being defined multiple times in the AndroidManifest.xml file instead of being merged into a single definition. Both the firebase.auth and the firebase.iid packages provide classes to be used by the ComponentDiscoveryService (firebase.iid is a dependency of firebase.messaging). These are added to the AndroidManifest.xml separately, and it seems that when a service is defined multiple times in the AndroidManifest, Android only uses the last definition and ignores earlier definitions that have the same service name. So the AndroidManifest ends up containing the following service definitions:
<service android:name="com.google.firebase.components.ComponentDiscoveryService" android:exported="false"> <meta-data android:name="com.google.firebase.components:com.google.firebase.auth.FirebaseAuthRegistrar" android:value="com.google.firebase.components.ComponentRegistrar" /> </service> <service android:name="com.google.firebase.components.ComponentDiscoveryService" android:exported="false"> <meta-data android:name="com.google.firebase.components:com.google.firebase.iid.Registrar" android:value="com.google.firebase.components.ComponentRegistrar" /> </service>Since the definition with FirebaseAuthRegistrar appears first, that definition ends up getting ignored and only the firebase.iid.Registrar class is registered for initialization.
As a workaround I tried adding a custom build task to merge the meta-data entries for any definitions of firebase.components.ComponentDiscoveryService, the generated service definition is shown below.
<service android:name="com.google.firebase.components.ComponentDiscoveryService" android:exported="false"> <meta-data android:name="com.google.firebase.components:com.google.firebase.auth.FirebaseAuthRegistrar" android:value="com.google.firebase.components.ComponentRegistrar" /> <meta-data android:name="com.google.firebase.components:com.google.firebase.iid.Registrar" android:value="com.google.firebase.components.ComponentRegistrar" /> </service>After this change the Firebase.Auth and Firebase.Iid instances are initialized successfully and the Firebase.Auth instance is no longer null.
thanks!
I'm testing the fix for that.
Any news on this? I'm having this issue with Auth & Messaging, they seem to work separately but not together.
Xamarin.Forms: 4.3.0.908675
Xamarin.GooglePlaySerices.Base: v71.1610.0
Xamarin.Firebase.Auth: 71.1605.0
Xamarin.Firebase.Messaging: 71.1740.0
@agust220 @xamarindevelopervietnam @GuillaumeSE @MatFillion
Can you try ManifestMerger and provide info if that works?
@agust220 @xamarindevelopervietnam @GuillaumeSE @MatFillion
Can you try ManifestMerger and provide info if that works?
Yep @moljac Xamarin.Android.ManifestMerger-preview03 fixed it.
Just installing through nuget in VS (with prerelease enabled) worked.
great to hear that!
Closing this one
Did not worked for me. getting this error at build time.
/Users/essence/.nuget/packages/xamarin.android.manifestmerger/1.0.0-preview03/build/monoandroid/Xamarin.Android.ManifestMerger.targets(5,5): Error MSB3073: The command ""/Users/essence/Library/Developer/Xamarin/jdk/microsoft_dist_openjdk_1.8.0.25/bin/java" -cp "/Users/essence/.nuget/packages/xamarin.android.manifestmerger/1.0.0-preview03/build/monoandroid/common.jar:/Users/essence/.nuget/packages/xamarin.android.manifestmerger/1.0.0-preview03/build/monoandroid/guava.jar:/Users/essence/.nuget/packages/xamarin.android.manifestmerger/1.0.0-preview03/build/monoandroid/kotlin-stdlib-jdk8.jar:/Users/essence/.nuget/packages/xamarin.android.manifestmerger/1.0.0-preview03/build/monoandroid/kotlin-stdlib.jar:/Users/essence/.nuget/packages/xamarin.android.manifestmerger/1.0.0-preview03/build/monoandroid/kxml2.jar:/Users/essence/.nuget/packages/xamarin.android.manifestmerger/1.0.0-preview03/build/monoandroid/manifest-merger.jar:/Users/essence/.nuget/packages/xamarin.android.manifestmerger/1.0.0-preview03/build/monoandroid/sdk-common.jar:/Users/essence/.nuget/packages/xamarin.android.manifestmerger/1.0.0-preview03/build/monoandroid/sdklib.jar" "com.android.manifmerger.Merger" --main "obj/Debug/android/AndroidManifest.xml" --libs "obj/Debug/lp/61/jl/AndroidManifest.xml:obj/Debug/lp/95/jl/AndroidManifest.xml:obj/Debug/lp/59/jl/AndroidManifest.xml:obj/Debug/lp/92/jl/AndroidManifest.xml:obj/Debug/lp/66/jl/AndroidManifest.xml:obj/Debug/lp/50/jl/AndroidManifest.xml:obj/Debug/lp/68/jl/AndroidManifest.xml:obj/Debug/lp/57/jl/AndroidManifest.xml:obj/Debug/lp/35/jl/AndroidManifest.xml:obj/Debug/lp/69/jl/AndroidManifest.xml:obj/Debug/lp/56/jl/AndroidManifest.xml:obj/Debug/lp/51/jl/AndroidManifest.xml:obj/Debug/lp/58/jl/AndroidManifest.xml:obj/Debug/lp/67/jl/AndroidManifest.xml:obj/Debug/lp/93/jl/AndroidManifest.xml:obj/Debug/lp/94/jl/AndroidManifest.xml:obj/Debug/lp/60/jl/AndroidManifest.xml:obj/Debug/lp/34/jl/AndroidManifest.xml:obj/Debug/lp/33/jl/AndroidManifest.xml:obj/Debug/lp/29/jl/AndroidManifest.xml:obj/Debug/lp/42/jl/AndroidManifest.xml:obj/Debug/lp/89/jl/AndroidManifest.xml:obj/Debug/lp/73/jl/AndroidManifest.xml:obj/Debug/lp/80/jl/AndroidManifest.xml:obj/Debug/lp/28/jl/AndroidManifest.xml:obj/Debug/lp/10/jl/AndroidManifest.xml:obj/Debug/lp/75/jl/AndroidManifest.xml:obj/Debug/lp/81/jl/AndroidManifest.xml:obj/Debug/lp/72/jl/AndroidManifest.xml:obj/Debug/lp/44/jl/AndroidManifest.xml:obj/Debug/lp/88/jl/AndroidManifest.xml:obj/Debug/lp/38/jl/AndroidManifest.xml:obj/Debug/lp/36/jl/AndroidManifest.xml:obj/Debug/lp/31/jl/AndroidManifest.xml:obj/Debug/lp/91/jl/AndroidManifest.xml:obj/Debug/lp/65/jl/AndroidManifest.xml:obj/Debug/lp/62/jl/AndroidManifest.xml:obj/Debug/lp/96/jl/AndroidManifest.xml:obj/Debug/lp/54/jl/AndroidManifest.xml:obj/Debug/lp/98/jl/AndroidManifest.xml:obj/Debug/lp/53/jl/AndroidManifest.xml:obj/Debug/lp/37/jl/AndroidManifest.xml:obj/Debug/lp/39/jl/AndroidManifest.xml:obj/Debug/lp/52/jl/AndroidManifest.xml:obj/Debug/lp/55/jl/AndroidManifest.xml:obj/Debug/lp/97/jl/AndroidManifest.xml:obj/Debug/lp/63/jl/AndroidManifest.xml:obj/Debug/lp/64/jl/AndroidManifest.xml:obj/Debug/lp/90/jl/AndroidManifest.xml:obj/Debug/lp/46/jl/AndroidManifest.xml:obj/Debug/lp/79/jl/AndroidManifest.xml:obj/Debug/lp/41/jl/AndroidManifest.xml:obj/Debug/lp/83/jl/AndroidManifest.xml:obj/Debug/lp/77/jl/AndroidManifest.xml:obj/Debug/lp/48/jl/AndroidManifest.xml:obj/Debug/lp/70/jl/AndroidManifest.xml:obj/Debug/lp/71/jl/AndroidManifest.xml:obj/Debug/lp/76/jl/AndroidManifest.xml:obj/Debug/lp/82/jl/AndroidManifest.xml:obj/Debug/lp/49/jl/AndroidManifest.xml:obj/Debug/lp/40/jl/AndroidManifest.xml:obj/Debug/lp/47/jl/AndroidManifest.xml:obj/Debug/lp/78/jl/AndroidManifest.xml" --out "obj/Debug/android/AndroidManifest.xml"" exited with code 1. (MSB3073)
Nuget packages used are,
<ItemGroup>
<PackageReference Include="Xamarin.Essentials">
<Version>1.3.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="4.3.0.991211" />
<PackageReference Include="Xamarin.Android.Maps.Utils">
<Version>0.5.1-beta2</Version>
</PackageReference>
<PackageReference Include="ZXing.Net.Mobile">
<Version>2.4.1</Version>
</PackageReference>
<PackageReference Include="Twilio.Voice.Android.XamarinBinding">
<Version>4.0.0</Version>
</PackageReference>
<PackageReference Include="Xbindings.ReLinker.Droid">
<Version>1.2.3</Version>
</PackageReference>
<PackageReference Include="Xamarin.Plugin.FilePicker">
<Version>2.1.34</Version>
</PackageReference>
<PackageReference Include="Twilio.Chat.Xamarin">
<Version>0.5.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Support.v4">
<Version>28.0.0.3</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat">
<Version>28.0.0.3</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Support.v7.CardView">
<Version>28.0.0.3</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Support.v7.MediaRouter">
<Version>28.0.0.3</Version>
</PackageReference>
<PackageReference Include="Xamarin.GooglePlayServices.Basement">
<Version>71.1620.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.GooglePlayServices.Tasks">
<Version>71.1601.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.GooglePlayServices.Base">
<Version>71.1610.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.GooglePlayServices.Location">
<Version>71.1600.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.GooglePlayServices.Maps">
<Version>71.1610.0</Version>
</PackageReference>
<PackageReference Include="Xam.Plugin.Media">
<Version>4.4.8-beta</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Common">
<Version>71.1610.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Iid">
<Version>71.1710.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Build.Download">
<Version>0.4.11</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Crashlytics">
<Version>2.9.4.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Crashlytics.Answers">
<Version>1.4.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Analytics">
<Version>71.1630.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Core">
<Version>71.1601.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Analytics.Impl">
<Version>71.1630.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Crashlytics.Beta">
<Version>1.2.9</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Crashlytics.Core">
<Version>2.6.3</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Messaging">
<Version>71.1740.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Fabric">
<Version>1.4.3</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.ManifestMerger">
<Version>1.0.0-preview03</Version>
</PackageReference>
</ItemGroup>
Same here, getting the Error MSB3073 @moljac
@Yogeshk25
@vincentcastagna
Please, open new issue with details (as much as possible, OS, VS version, Android SDK version, ...)
I resolved it by removing following packages from my android project,
<PackageReference Include="Xamarin.Firebase.Common">
<Version>71.1610.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Iid">
<Version>71.1710.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Core">
<Version>71.1601.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Analytics.Impl">
<Version>71.1630.0</Version>
</PackageReference>
it seems like problem was Xamarin.Firebase.Core package.
I resolved it by removing following packages from my android project,
<PackageReference Include="Xamarin.Firebase.Common"> <Version>71.1610.0</Version> </PackageReference> <PackageReference Include="Xamarin.Firebase.Iid"> <Version>71.1710.0</Version> </PackageReference> <PackageReference Include="Xamarin.Firebase.Core"> <Version>71.1601.0</Version> </PackageReference> <PackageReference Include="Xamarin.Firebase.Analytics.Impl"> <Version>71.1630.0</Version> </PackageReference>it seems like problem was Xamarin.Firebase.Core package.
Thank you. That's work for me. I deleted Xamarin.GooglePlayServices.Gcm, Xamarin.Firebase.Core and Xamarin.Firebase.Measurement.Connector.impl
Most helpful comment
I encountered this issue as well, after looking into it I think the issue is caused by the firebase service com.google.firebase.components.ComponentDiscoveryService being defined multiple times in the AndroidManifest.xml file instead of being merged into a single definition. Both the firebase.auth and the firebase.iid packages provide classes to be used by the ComponentDiscoveryService (firebase.iid is a dependency of firebase.messaging). These are added to the AndroidManifest.xml separately, and it seems that when a service is defined multiple times in the AndroidManifest, Android only uses the last definition and ignores earlier definitions that have the same service name. So the AndroidManifest ends up containing the following service definitions:
Since the definition with FirebaseAuthRegistrar appears first, that definition ends up getting ignored and only the firebase.iid.Registrar class is registered for initialization.
As a workaround I tried adding a custom build task to merge the meta-data entries for any definitions of firebase.components.ComponentDiscoveryService, the generated service definition is shown below.
After this change the Firebase.Auth and Firebase.Iid instances are initialized successfully and the Firebase.Auth instance is no longer null.