DEV Community

Victor Hugo Garcia
Victor Hugo Garcia

Posted on • Edited on

41

Firebase Crashlytics in .NET MAUI

Firebase is an app development platform that helps you build and grow apps. Firebase Crashlytics is an error reporting solution available at no charge. In this post, I’ll show you how to implement Firebase Crashlytics in your .NET MAUI app.


Setup a Firebase project

  • Create a Firebase project in the Firebase Console, if you don't already have one by clicking Add Project button.

  • Make sure you enabled Google Analytics in your project.

  • Add GoogleService-Info.plist for iOS and google-services.json for Android files to your app project at the root level.

  • Right-click the GoogleService-Info.plist file and set the build action to Bundle Resource, then right-click the google-services.json and set build action to GoogleServicesJson.

Required packages and project conditions

  • Add the NuGet packages required to enable Firebase Crashlytics on iOS and Android or edit the .csproj file and set them up there:

Android

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0-android'">
      <GoogleServicesJson Include="google-services.json" />
      <PackageReference Include="Xamarin.Firebase.Core" Version="121.1.1" />
      <PackageReference Include="Xamarin.Firebase.Crashlytics" Version="118.2.13" />
</ItemGroup>

Enter fullscreen mode Exit fullscreen mode

Create a strings.xml file under the following folder: Platforms/Android/Resources/values and set the following content

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="google_app_id"><!-- YOUR APP ID FROM FIREBASE --></string>
    <string name="com.crashlytics.android.build_id">2.0</string>
</resources>
Enter fullscreen mode Exit fullscreen mode

iOS

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0-ios'">
        <BundleResource Include="GoogleService-Info.plist" />
        <PackageReference Include="Xamarin.Firebase.iOS.Crashlytics" Version="8.10.0.1" />
</ItemGroup>
Enter fullscreen mode Exit fullscreen mode

Initialize the Firebase services

In the MauiProgram.cs file, the Firebase services must be initialized.

private static MauiAppBuilder RegisterFirebase(this MauiAppBuilder builder)
    {
        builder.ConfigureLifecycleEvents(events =>
        {
#if IOS
            events.AddiOS(iOS => iOS.FinishedLaunching((app, launchOptions) => {
                Firebase.Core.App.Configure();
Firebase.Crashlytics.Crashlytics.SharedInstance.Init();
Firebase.Crashlytics.Crashlytics.SharedInstance.SetCrashlyticsCollectionEnabled(true);
Firebase.Crashlytics.Crashlytics.SharedInstance.SendUnsentReports();
                return false;
            }));
#else
            events.AddAndroid(android => android.OnCreate((activity, bundle) => {
                Firebase.FirebaseApp.InitializeApp(activity);
            }));
#endif
        });

        return builder;
    }
Enter fullscreen mode Exit fullscreen mode

Then on the static CreateMauiApp method register the Firebase Services:
builder.RegisterFirebase();

Rebuild and Run

Up to this point, Firebase Crashlytics should be identified by the Firebase console and waiting for the first crash.

Image description

Log non-fatal exceptions

We all have at least one try and catch in our app somewhere, or maybe a custom validation you would like to log and track into Crashlytics that may be important for your app to function properly. Please find below how I integrated this by using platform-specific API.

Why platform-specific API?

Well, I found this way easier to maintain and update over time. If you want to support macOS and/or Windows, well the code below is ready for you to add the supported platform API for logging custom events.

using Firebase.Crashlytics;
#if IOS
using Foundation;
#else
using Firebase;
#endif
namespace DemoApp.Services.Firebase;
public interface IFirebaseCrashlyticsService
{
void Log(Exception ex);
}
public class FirebaseCrashlyticsService : IFirebaseCrashlyticsService
{
public void Log(Exception ex)
{
#if IOS
var errorInfo = new Dictionary<object, object> {
{ NSError.LocalizedDescriptionKey, NSBundle.MainBundle.GetLocalizedString(ex.Message, null) },
{ NSError.LocalizedFailureReasonErrorKey, NSBundle.MainBundle.GetLocalizedString ("Managed Failure", null) },
{ NSError.LocalizedRecoverySuggestionErrorKey, NSBundle.MainBundle.GetLocalizedString ("Recovery Suggestion", null) },
//{ "ProductId", "123456" }, you can append even custom information if needed
};
var error = new NSError(new NSString("NonFatalError"),
-1001,
NSDictionary.FromObjectsAndKeys(errorInfo.Values.ToArray(), errorInfo.Keys.ToArray(), errorInfo.Keys.Count));
Crashlytics.SharedInstance.RecordError(error);
#else
FirebaseCrashlytics.Instance.RecordException(Java.Lang.Throwable.FromException(ex));
#endif
}
}

Then apply some Dependency Injection for registering the services in the MauiProgram.cs file and log a custom event from any ViewModel or View:

try
{
    // Sample code goes here
}
catch(Exception ex)
{
    Debug.WriteLine(ex.ToString());
    _firebaseCrashlyticsService.Log(ex);
}
Enter fullscreen mode Exit fullscreen mode

Thanks for reading! Follow me on Twitter @ivictorhugo

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more