Can we get custom events such as say Button 1 was pressed using Firebase Analytics in a Xamarin Forms Project ?
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.
Reference the proper nuget packages for Firebase Analytics:
Android Project
Forms.Context
is deprecated)
iOS Project
In your PCL (or .NETStandard) project create the interface
LogEvent
method to store your eventNote: 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
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);
}
}
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"
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
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");
}
}