Can we get custom events such as say Button 1 was pressed using Firebase Analytics in a Xamarin Forms Project ?
3 Answers
Answer Updated for the new version of Xamarin Firebase components and to fix various issues
Sure, you need to DI (dependency injection) to call the platform code.
- Configure your Firebase App: https://firebase.google.com/docs/projects/learn-more
Reference the proper nuget packages for Firebase Analytics:
Android Project
- Xamarin.FireBase.Analytics
- Xamarin.FireBase.Analytics.Impl
- Plugin.CurrentActivity (used to get the current context as
Forms.Context
is deprecated)
iOS Project
- Xamarin.FireBase.iOS.Analytics (iOS project)
In your PCL (or .NETStandard) project create the interface
- In the Android and iOS project write the plaftorm specific code
- In your viewmodels, use DI in the PCL (or .NETStandard) project to call the
LogEvent
method to store your event
Note: Custom events are slow to appear in firebase, in my experience they need 24 hours to appear in the web console. If you want to properly test the custom logging, use your phone and activate the analytics debug (so you can see your events in the debugView in firebase console)*
Note2: watch out for the
eventId
property: names can be up to 40 characters long, may only contain alphanumeric characters and underscores (""), and must start with an alphabetic character. The "firebase", "google_" and "ga_" prefixes are reserved and should not be used. I have included a smal utility function to automatically fix eventId, you can skip it if you want
PCL or .NETStandard project
using System.Collections.Generic;
namespace MobileApp.Services
{
public interface IAnalyticsService
{
void LogEvent(string eventId);
void LogEvent(string eventId, string paramName, string value);
void LogEvent(string eventId, IDictionary<string, string> parameters);
}
}
Android
Make sure to have the INTERNET permission in your manifest.
Import your google-services.json (generated from your firebase account) with compilation action set to "GoogleServicesJson"
Remember to call CrossCurrentActivity
init method in your AppDelegate OnCreate
:
CrossCurrentActivity.Current.Init(this, bundle);
This is the Android platform service code:
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Android.OS;
using Firebase.Analytics;
using Plugin.CurrentActivity;
using MobileApp.Services;
namespace MobileApp.Droid.Services
{
[assembly: Dependency (typeof(AnalyticsServiceDroid))]
public class AnalyticsServiceDroid : IAnalyticsService
{
public void LogEvent(string eventId)
{
LogEvent(eventId, null);
}
public void LogEvent(string eventId, string paramName, string value)
{
LogEvent(eventId, new Dictionary<string, string>
{
{paramName, value}
});
}
public void LogEvent(string eventId, IDictionary<string, string> parameters)
{
//utility method to fix eventId, you can skip it if you are sure to always pass valid eventIds
eventId = FixEventId(eventId);
var fireBaseAnalytics = FirebaseAnalytics.GetInstance(CrossCurrentActivity.Current.AppContext);
if (parameters == null)
{
fireBaseAnalytics.LogEvent(eventId, null);
return;
}
var bundle = new Bundle();
foreach (var item in parameters)
{
bundle.PutString(item.Key, item.Value);
}
fireBaseAnalytics.LogEvent(eventId, bundle);
}
//utility method to fix eventId, you can skip it if you are sure to always pass valid eventIds
private string FixEventId(string eventId)
{
if (string.IsNullOrWhiteSpace(eventId))
return "unknown";
//remove unwanted characters
eventId = Regex.Replace(eventId, @"[^a-zA-Z0-9_]+", "_", RegexOptions.Compiled);
//trim to 40 if needed
return eventId.Substring(0, Math.Min(40, eventId.Length));
}
}
}
Debug View in Android
To enable the debugView in the firebase run this command from your adb console command prompt (usually is c:\WINDOWS\System32
, but you can reach it through Visual Studio in tools --> android --> android adb command prompt
):
adb shell setprop debug.firebase.analytics.app <package_name>
To disable the debugView use:
adb shell setprop debug.firebase.analytics.app .none.
Verbose logging
Verbose logging is usefyk to monitor logging of events by the SDK to help verify that events are being logged properly. This includes both automatically and manually logged events.
You can enable verbose logging with a series of adb commands:
adb shell setprop log.tag.FA VERBOSE
adb shell setprop log.tag.FA-SVC VERBOSE
adb logcat -v time -s FA FA-SVC
Important note
Some external libraries (Like MS AppCenter) are already including Firebase and explicitly disabling analytics in teir manifest.
In these cases you need to modify your
AndroidManifest.xml
adding this line just before the</application>
tag:<meta-data android:name="firebase_analytics_collection_deactivated" android:value="false" tools:replace="android:value"/>
Also make sure to have this property inside your
<manifest>
tag:xmlns:tools="http://schemas.android.com/tools"
iOS
Make sure to test the event logging on your phone! This is not going to work anymore on emulators
Initialize the component in your AppDelegate, just before base.FinishedLaunching:
Firebase.Core.App.Configure();
Then import your GoogleService-Info.plist (generated from your firebase account) with compilation action set to "BundleResource" .
This is the iOS platform service code:
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Firebase.Analytics;
using Firebase.Core;
using Foundation;
using MobileApp.Services;
namespace MobileApp.iOS.Services
{
[assembly: Dependency (typeof(AnalyticsServiceIOS))]
public class AnalyticsServiceIOS : IAnalyticsService
{
public void LogEvent(string eventId)
{
LogEvent(eventId, (IDictionary<string, string>)null);
}
public void LogEvent(string eventId, string paramName, string value)
{
LogEvent(eventId, new Dictionary<string, string>
{
{ paramName, value }
});
}
public void LogEvent(string eventId, IDictionary<string, string> parameters)
{
//utility method to fix eventId, you can skip it if you are sure to always pass valid eventIds
eventId = FixEventId(eventId);
if (parameters == null)
{
Analytics.LogEvent(eventId, parameters: null);
return;
}
var keys = new List<NSString>();
var values = new List<NSString>();
foreach (var item in parameters)
{
keys.Add(new NSString(item.Key));
values.Add(new NSString(item.Value));
}
var parametersDictionary =
NSDictionary<NSString, NSObject>.FromObjectsAndKeys(values.ToArray(), keys.ToArray(), keys.Count);
Analytics.LogEvent(eventId, parametersDictionary);
}
//utility method to fix eventId, you can skip it if you are sure to always pass valid eventIds
private string FixEventId(string eventId)
{
if (string.IsNullOrWhiteSpace(eventId))
return "unknown";
//remove unwanted characters
eventId = Regex.Replace(eventId, @"[^a-zA-Z0-9_]+", "_", RegexOptions.Compiled);
//trim to 40 if needed
return eventId.Substring(0, Math.Min(40, eventId.Length));
}
}
}
Debug View in iOS
To enable the debugView in the firebase console add the following argument to Extra mlaunch Arguments in your iOS project properties:
--argument=-FIRDebugEnabled
To disable the debugView use:
--argument=-FIRDebugDisabled
Important note (thanks to Ken for pointing out this)
If you get an exception calling
Firebase.Core.App.Configure();
in your AppDelegate, modify yourGoogleService-Info.plist
settingsIS_ANALYTICS_ENABLED
totrue
In your ViewModel you can track any event you want
For Example:
public class MenuPageViewModel{
public MenuPageViewModel(){
var analyticsService= DependencyService.Get<IAnalyticsService>();
//You can use any of the LogEvent Overloads, for example:
analyticsService.LogEvent("Event");
}
}

- 1,428
- 1
- 15
- 21
-
Firebase analytics is bad for xamarin crash analytics. It's better to use microsoft appcenter. https://appcenter.ms/ – Access Denied Feb 20 '19 at 03:54
-
2i'm using it for tracking analytical data (page views, user engagement, custom events, time on screens, ecc...). Last time i checked, appcenter was waaay behind Firebase regarding the analytics part. I think i'll need to re-check it! Maybe you are speaking about Firebase Crashlytics? This is another topic. Firebase Crash Reporting has been discountinued and retired months ago. – GiampaoloGabba Feb 20 '19 at 23:30
-
@GiampaoloGabba analyticsService.LogEvent("EventId","EventValue"); throwing System.NullReferenceException: 'Object reference not set to an instance of an object.' error – Shanmugasundharam Nov 11 '19 at 03:56
-
@Shanmugasundharam the example code was wrong, the interface does not provide an overload with 2 strings. i have updated the answer. Also make sure to register the platform services with the DI container – GiampaoloGabba Nov 16 '19 at 19:29
-
@GiampaoloGabba thanks for the update, I have also updated my code and its got working fine, but unable to read the data from my events. i guess big query will provide the raw data. – Shanmugasundharam Nov 18 '19 at 02:41
-
@GiampaoloGabba. Thank you! On Visual Studio 2019 for Mac, You access to Adb shell by clicking on menu :Tools/SDK Command prompt – Sébastien REMY Mar 28 '20 at 09:20
your android service file is erroneous
Your code below
var bundle = new Bundle();
foreach (var item in parameters)
{
bundle.PutString(FirebaseAnalytics.Param.ItemId, item.Key);
bundle.PutString(FirebaseAnalytics.Param.ItemName, item.Value);
}
must be replaced with the following to track all parameters:
var bundle = new Bundle();
foreach (var item in parameters)
{
bundle.PutString(item.Key, item.Value);
}
-
1Thank you. My code was for "suggested" firebase events but was working even for the custom ones. However, your is better :) Answer updated! – GiampaoloGabba May 22 '19 at 16:32