A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
Hello @Vignesh Palthurai ,
Sorry for the late response.
Please follow these steps:
- Choose a unique Bundle ID
In MauiApp2.csproj, set a unique bundle ID (free Apple accounts require it to be globally unique):
<ApplicationId>com.nancy.mauiapp2</ApplicationId>
- Bundle the plist into the app
Place GoogleService-Info.plist in iOS and add to MauiApp2.csproj:
<ItemGroup Condition="'$(TargetFramework)' == 'net10.0-ios'">
<BundleResource Include="Platforms\iOS\GoogleService-Info.plist">
<Link>GoogleService-Info.plist</Link>
</BundleResource>
</ItemGroup>
Note: The <Link> tag is critical — it places the file at the app bundle root where Firebase expects it.
- Add the following code to
.csprj:
<PropertyGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
<_ExportSymbolsExplicitly>false</_ExportSymbolsExplicitly>
</PropertyGroup>
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
<_ReferencesLinkerFlags Include="-u __mh_execute_header" />
</ItemGroup>
- Handle the dSYM warning (if it appears)
If you see a message like "1 unprocessed crash", it means the crash was captured, but Firebase needs the dSYM file to display a human-readable stack trace.
To upload it:
- Locate the file: bin > Debug > net10.0-ios > MauiApp2.app.dSYM
- In Firebase Console → Crashlytics → dSYMs tab → click Manage
- Upload the .dSYM folder (zip it first)
After uploading, the crash will be fully symbolicated and readable.
Note: Please replace all private information such as my project name (MauiApp2) and ApplicationId with your own.
You can refer to my following example code:
.csprj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0-android</TargetFrameworks>
<TargetFrameworks Condition="!$([MSBuild]::IsOSPlatform('linux'))">$(TargetFrameworks);net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net10.0-windows10.0.19041.0</TargetFrameworks>
<!-- Note for MacCatalyst:
The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifier>.
The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
<!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->
<OutputType>Exe</OutputType>
<RootNamespace>MauiApp2</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Enable XAML source generation for faster build times and improved performance.
This generates C# code from XAML at compile time instead of runtime inflation.
To disable, remove this line.
For individual files, you can override by setting Inflator metadata:
<MauiXaml Update="MyPage.xaml" Inflator="Default" /> (reverts to defaults: Runtime for Debug, XamlC for Release)
<MauiXaml Update="MyPage.xaml" Inflator="Runtime" /> (force runtime inflation) -->
<MauiXamlInflator>SourceGen</MauiXamlInflator>
<!-- Display name -->
<ApplicationTitle>MauiApp2</ApplicationTitle>
<!-- App Identifier -->
<ApplicationId>com.nancy.mauiapp2</ApplicationId>
<!-- Versions -->
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
<WindowsPackageType>None</WindowsPackageType>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">23.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
</PropertyGroup>
<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
<!-- Splash Screen -->
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />
<!-- Images -->
<MauiImage Include="Resources\Images\*" />
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />
<!-- Custom Fonts -->
<MauiFont Include="Resources\Fonts\*" />
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
<ItemGroup>
<None Remove="Platforms\Android\Resources\values\strings.xml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="10.0.51" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.6" />
<PackageReference Include="Plugin.Firebase" Version="4.0.0" />
<PackageReference Include="Plugin.Firebase.Analytics" Version="4.0.0" />
<PackageReference Include="Plugin.Firebase.Crashlytics" Version="4.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net10.0-android'">
<GoogleServicesJson Include="Platforms\Android\google-services.json" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net10.0-ios'">
<BundleResource Include="Platforms\iOS\GoogleService-Info.plist">
<Link>GoogleService-Info.plist</Link>
</BundleResource>
</ItemGroup>
<PropertyGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
<_ExportSymbolsExplicitly>false</_ExportSymbolsExplicitly>
</PropertyGroup>
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
<_ReferencesLinkerFlags Include="-u __mh_execute_header" />
</ItemGroup>
</Project>
MauiProgram.cs:
using Microsoft.Extensions.Logging;
using Microsoft.Maui.LifecycleEvents;
#if IOS || ANDROID
using Plugin.Firebase.Analytics;
using Plugin.Firebase.Crashlytics;
using Plugin.Firebase.Bundled.Shared;
#endif
#if IOS
using ObjCRuntime;
using Plugin.Firebase.Bundled.Platforms.iOS;
#elif ANDROID
using Plugin.Firebase.Bundled.Platforms.Android;
#endif
namespace MauiApp2;
public static class MauiProgram
{
public static string? FirebaseInitError { get; private set; }
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.RegisterFirebaseServices()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
private static MauiAppBuilder RegisterFirebaseServices(this MauiAppBuilder builder)
{
#if IOS || ANDROID
builder.ConfigureLifecycleEvents(events =>
{
#if IOS
events.AddiOS(iOS => iOS.WillFinishLaunching((_, _) =>
{
try
{
CrossFirebase.Initialize(CreateCrossFirebaseSettings());
CrossFirebaseCrashlytics.Current.SetCrashlyticsCollectionEnabled(true);
CrossFirebaseCrashlytics.Current.SendUnsentReports();
Runtime.MarshalManagedException += (_, args) =>
{
args.ExceptionMode = MarshalManagedExceptionMode.UnwindNativeCode;
};
AppDomain.CurrentDomain.UnhandledException += (_, args) =>
{
if (args.ExceptionObject is Exception ex)
{
CrossFirebaseCrashlytics.Current.Log($"Fatal: {ex.GetType().Name}: {ex.Message}");
CrossFirebaseCrashlytics.Current.RecordException(ex);
}
};
}
catch (Exception ex)
{
FirebaseInitError = $"{ex.GetType().Name}: {ex.Message}";
System.Diagnostics.Debug.WriteLine($"Firebase init error: {ex}");
}
return true;
}));
#elif ANDROID
events.AddAndroid(android => android.OnCreate((activity, _) =>
{
CrossFirebase.Initialize(
activity,
() => Microsoft.Maui.ApplicationModel.Platform.CurrentActivity,
CreateCrossFirebaseSettings()
);
FirebaseAnalyticsImplementation.Initialize(activity);
}));
#endif
});
builder.Services.AddSingleton(_ => CrossFirebaseAnalytics.Current);
builder.Services.AddSingleton(_ => CrossFirebaseCrashlytics.Current);
#endif
return builder;
}
#if IOS || ANDROID
private static CrossFirebaseSettings CreateCrossFirebaseSettings()
{
return new CrossFirebaseSettings(
isAnalyticsEnabled: true,
isCrashlyticsEnabled: true
);
}
#endif
}
MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp2.MainPage">
<VerticalStackLayout Padding="30" Spacing="20" VerticalOptions="Center">
<Label Text="Firebase Test App" FontSize="Large" HorizontalOptions="Center" />
<Button Text="Log Analytics Event" Clicked="OnLogEventClicked" />
<Button Text="Force Test Crash (Crashlytics)"
Clicked="OnCrashClicked"
BackgroundColor="Red" TextColor="White" />
</VerticalStackLayout>
</ContentPage>
MainPae.xaml.cs:
using Plugin.Firebase.Analytics;
using Plugin.Firebase.Crashlytics;
#if IOS
using Foundation;
using System.Runtime.InteropServices;
#endif
namespace MauiApp2
{
public partial class MainPage : ContentPage
{
int count = 0;
#if IOS
[DllImport("libSystem.dylib")]
private static extern void abort();
#endif
public MainPage()
{
InitializeComponent();
}
private void OnLogEventClicked(object sender, EventArgs e)
{
CrossFirebaseAnalytics.Current.LogEvent("test_button_clicked",
new Dictionary<string, object> { { "button", "analytics_test" } });
DisplayAlert("Analytics", "Event sent to Firebase!!!", "OK");
}
private void OnCrashClicked(object sender, EventArgs e)
{
if (MauiProgram.FirebaseInitError != null)
{
DisplayAlert("Firebase Init FAILED", MauiProgram.FirebaseInitError, "OK");
return;
}
if (CrossFirebaseCrashlytics.Current == null)
{
DisplayAlert("Crashlytics ERROR", "CrossFirebaseCrashlytics.Current is null — Firebase did not initialize.", "OK");
return;
}
CrossFirebaseCrashlytics.Current.Log("About to trigger fatal test crash via abort()");
#if IOS
abort();
#else
throw new Exception("[Test] Fatal crash triggered by user");
#endif
}
}
}
AppDelegate.cs:
using Foundation;
namespace MauiApp2
{
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
}
I tested this on my end and it works. Please try and let me know the results. I'd happy to investigate further.
If any part of my explanation helped address your question, I would greatly appreciate it if you could follow the instructions here. This can also help other community members facing similar scenarios. Thank you so much.